一些實用的單片機c程序

2020-12-17 電子產品世界
//16進位10進位互換程序


unsigned char d[10]; //用於顯示的10位顯示緩存

本文引用地址:http://www.eepw.com.cn/article/201612/325237.htm

//========================================================
//16進位to10進位輸出子程序:顯示數據,起始位,結束位,有無小數點
//========================================================
void output(unsigned long dd,unsigned char s,unsigned char
e,unsigned char dip) {
unsigned long div;
unsigned char tm[8],i,j;
div=10000000;
for (i=0;i<8;i++) {
tm[i]=dd/div;
dd%=div;
div/=10;
}
for (i=0;i<6;i++) {
if (tm[i]!=0) break;
tm[i]=nul;
}
tm[5]|=dip; //小數點控制,請看「串行LED數碼管顯示驅動程序」
j=7;
for (i=s;i d[i]=tm[j];
j--;
}
}

//把顯示位5-9位的10進位數轉換成為16進位數
unsigned int input(void) {
unsigned int dd,dat;
dd=10000;dat=0;
for (i=5;i<10;i++) {
dat+=dd*temp;
dd/=10;
}
return(dat);
}
/* 89C51系列CPU編程器接收CPU程序*/

#i nclude
#i nclude
#i nclude

#define e 8
#define p 9
#define l 10

sbit led=P3^2;
sbit p27=P2^7;
sbit p26=P2^6;
sbit p36=P3^6;
sbit p37=P3^7;
sbit rst=P3^3;
sbit ale=P3^5;
sbit vpp=P3^4;

bit b_break;
unsigned int adds;


// 13.8mS
void int_t0(void) interrupt 1 {
TH0=-100;
b_break=1;
}

void wait(unsigned char w) {
unsigned int t=w*184;
b_break=0;
TL0=-t%256-1;TH0=-t/256;
while (b_break==0) {}
}

void nop(void) {
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}

unsigned char command(void) {
TH0=-100;b_break=0;
while (RI==0) {if (b_break==1) return(0);}
RI=0;
return(SBUF);
}

void earsure(unsigned char cpu) {
switch (cpu) {
case 1: //89C51
case 2:rst=p26=1;p27=p36=p37=0;nop();vpp=1;nop();
ale=0;wait(110);ale=1;nop();
break;
case 3:
case 4:break;
case 5:
case 6:break;
}
}

void program(unsigned char cpu) {
unsigned int bdata adds=0;
unsigned char d;
switch (cpu) {
case 1: //89C51
case 2:
p36=p37=1;rst=1;
while (1) {
TH0=-100;b_break=0;
while (RI==0) {if (b_break==1) return;}
RI=0;
d=SBUF;
//address
P0=adds%256;
P2=adds/256;
p27=1;
//data
P1=d;
nop(); //48clcl
//vpp
vpp=1;
nop(); //48clcl
//ale
ale=0;
wait(1);//100uS
ale=1;
nop(); //10uS
vpp=0;
nop(); //48clcl
p27=0;
nop(); //48clcl
P1=0xff;
TH0=-100;b_break=0;
while (d!=P1) {if (b_break==1) return;} //data
polling
SBUF=d;
adds++;
}
break;
case 3:
case 4:
case 5:
case 6:break;
}
}

void lock(unsigned char cpu) {
unsigned char i;
switch (cpu) {
case 1: //89c51
case 2:
//lock 1
rst=p26=p36=p27=p37=1;nop();
vpp=1;
nop();
ale=0;
// for (i=0;i<6;i++) wait(100);
wait(1);
ale=1;
nop();
vpp=0;
nop();

//lock 2
rst=p26=p27=1;p36=p37=0;nop();
vpp=1;
nop();
ale=0;
// for (i=0;i<6;i++) wait(100);
wait(1);
ale=1;
nop();
vpp=0;
nop();

//lock 3
rst=p26=p36=1;p27=p37=0;nop();
vpp=1;
nop();
ale=0;
// for (i=0;i<6;i++) wait(100);
wait(1);
ale=1;
nop();
vpp=0;
nop();
break;
case 3:
case 4:
case 5:
case 6:break;
}
}

void main(void) {
unsigned char disp,flash,temp,cpu;
EA=1;
SCON=0xd8;PCON=0x80;
TMOD=0x21;
TL1=TH1=0xff;TR1=1;
TH0=-100;ET0=TR0=1;

flash=0x80;


while (1) {
temp=command();
switch (temp) {
case 0:
case 1: //89c51
case 2: //89C52
case 3: //80f51
case 4: //80F52
case 5: //87F51
case 6:cpu=temp;SBUF=temp;break;//87f52
case e:SBUF=temp;earsure(cpu);break; //erasure
case p:SBUF=temp;program(cpu);break; //program
case l:lock(cpu);SBUF=temp;break; //lock
default:SBUF=temp;break;
}
b_break=0;
if ((++disp)>flash) {disp=0;led=!led;}
}
}
//HT1380實時時鐘驅動程序

sbit clock_dat=P0^1;
sbit clock_clk=P0^2;
sbit clock_rst=P0^3;

sbit a0=ACC^0;
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;

void clock_out(unsigned char dd) {
ACC=dd;
clock_dat=a0;clock_clk=1;clock_clk=0;
clock_dat=a1;clock_clk=1;clock_clk=0;
clock_dat=a2;clock_clk=1;clock_clk=0;
clock_dat=a3;clock_clk=1;clock_clk=0;
clock_dat=a4;clock_clk=1;clock_clk=0;
clock_dat=a5;clock_clk=1;clock_clk=0;
clock_dat=a6;clock_clk=1;clock_clk=0;
clock_dat=a7;clock_clk=1;clock_clk=0;
}
unsigned char clock_in(void) {
clock_dat=1;
a0=clock_dat;
clock_clk=1;clock_clk=0;a1=clock_dat;
clock_clk=1;clock_clk=0;a2=clock_dat;
clock_clk=1;clock_clk=0;a3=clock_dat;
clock_clk=1;clock_clk=0;a4=clock_dat;
clock_clk=1;clock_clk=0;a5=clock_dat;
clock_clk=1;clock_clk=0;a6=clock_dat;
clock_clk=1;clock_clk=0;a7=clock_dat;
return(ACC);
}
unsigned char read_clock(unsigned char ord) {
unsigned char dd=0;
clock_clk=0;
clock_rst=0;
clock_rst=1;
clock_out(ord);
dd=clock_in();
clock_rst=0;
clock_clk=1;
return(dd);
}
void write_clock(unsigned char ord,unsigned char dd) {
clock_clk=0;
clock_rst=0;
clock_rst=1;
clock_out(ord);
clock_out(dd);
clock_rst=0;
clock_clk=1;
}
/*單個漢字庫字摸提取程序,tc2.0編譯*/
#i nclude "stdio.h"
#i nclude "dos.h"
#i nclude "process.h"
#i nclude "string.h"


void main(void) {
long int num_bytes,qm,wm;
unsigned char d,i,j,k,a[132],b[132];
unsigned char * data;
unsigned char * hz;
static unsigned char dd[103];
FILE *fp;

if ((fp=fopen("hzk16f","rb"))==NULL) {
printf("cant open hzk16\n");
exit(1);
}
clrscr();
while (1) {

data=(unsigned char *) malloc(33);
printf("please input:\n");
scanf("%s",dd); /*輸入一個漢字*/

qm=* dd; /*通過區位碼計算其在hzk16f文件中的偏移地址*/
qm=qm-161;
if (qm>87) exit(0);
wm=* (dd+1);
wm=wm-161;
if (wm>94) exit(0);
num_bytes=((long)qm*94+wm)*32;
fseek(fp,num_bytes,SEEK_SET);
fgets(data,33,fp);
for (i=0;i<32;i++) b[i]=* data++;
for (i=0;i<32;i+=2) a[i/2]=b[i];
for (i=0;i<32;i+=2) a[i/2+16]=b[i+1];
for (i=8;i<16;i++) b[i]=a[i];
for (i=8;i<16;i++) a[i]=a[i+8];
for (i=8;i<16;i++) a[i+8]=b[i];

/*轉換,hzf16f在電腦的儲存格式是以行為字節計算的,一般的lcd都採用以列為字節計算*/
for (k=0;k<32;k+=8) {
for (j=0;j<8;j++) {
d=0;
for (i=0;i<8;i++) {
if (a[i+k]>=0x80) {
switch (i) {
case 0:d+=1;break;
case 1:d+=2;break;
case 2:d+=4;break;
case 3:d+=8;break;
case 4:d+=0x10;break;
case 5:d+=0x20;break;
case 6:d+=0x40;break;
case 7:d+=0x80;break;
}
}
}
for (i=0;i<8;i++) a[i+k]<<=1;
b[j+k]=d;
}
}
clrscr();
printf("/*%s:*/\n",dd); /*輸出0x00格式的16進位數*/
for (k=0;k<32;k+=8) {
for (j=0;j<8;j++) printf("0x%x,",b[j+k]);
printf("\n");
}
getch();
}
}
//按鍵掃描驅動程序

unsigned char key,key_h,kpush;
unsigned int key_l;

//按鍵連接到p1.0、p1.1、p1.2

void int_t0(void) interrupt 1 {
unsigned char dd,i;
TL0=TL0+30;TH0=0xfb; //800
/* 按鍵判別 */
if ((P1&0x7)==0x7) {
if ((key_l>30)&&(key_l<800)&&(key_h>30)) {
//釋放按鍵,如果之前按鍵時間少於1秒,讀入鍵值
key=kpush;
}
if ((++key_h)>200) key_h=200;
key_l=0;
if (key>=0x80) key=0;
//如果之前的按鍵為長按1秒,清除鍵值
} else {
kpush=P1&0x7;
key_l++;
if ((key_l>800)&&(key_h>30)) {
//如果按鍵超過1秒,鍵值加0x80標誌長按鍵
key=kpush|0x80;
key_h=0;
key_l=0;
}
}
}
void main(void) {
TMOD=0x1;TR0=1;ET0=1;EA=1;
while (1) {
while (!key) {}
switch (key) {
case 1:break;
case 2:break;
}
}
//串行驅動led顯示,
//一個74hc595位移寄存器驅動三極體驅動led位,
//兩個74hc595驅動led段,方式位5位x8段x2=10個數碼管
//5分頻,每次掃描時間位1.25ms


//定義特殊符號

#define nul 0xf
#define qc 0xc
#define qb 0xb
#define q_ 0xa
#define q__ 0xd
#define q___ 0xe
#define qp 0x10
#define qe 0x11
#define qj 0x12
#define qn 0x13
#define qf 0x14
#define qa 0x15
#define qr 0x16
#define qd 0x17
#define qu 0x18
#define ql 0x19
#define qh 0x1a
#define qwen 0x1b
#define qt 0x1c
#define qla 0x1d
#define qlb 0x1e
#define qlc 0x1f
#define qld 0x20
#define qle 0x21
#define qlf 0x22
#define qlg 0x23
#define qldp 0x24


//顯示段信息,不同led排列組合的段信息只需更改8個數值即可。
//因此,該定義具有通用性。

// 顯示
// -d 20
// |c 40 |e 10
// - g 80
// |b 2 |f 4
// _a1 .dp 8
#define pa 1
#define pb 2
#define pc 0x40
#define pd 0x20
#define pe 0x10
#define pf 4
#define pg 0x80
#define pdp 8

//--------------
#define l0 pdp+pg
#define l1 255-pf-pe
#define l2 pdp+pc+pf
#define l3 pdp+pc+pb
#define l4 pdp+pa+pb+pd
#define l5 pdp+pb+pe
#define l6 pdp+pe
#define l7 pdp+pc+pg+pb+pa
#define l8 pdp
#define l9 pdp+pb
#define la pdp+pa
#define lb pdp+pd+pe
#define lc pdp+pg+pe+pf
#define ld pdp+pc+pd
#define le pdp+pe+pf
#define lf pdp+pe+pf+pa
#define l_ 255-pg
#define lnul 255
#define ll pdp+pg+pd+pf+pe
#define lp pdp+pa+pf
#define lt pdp+pd+pe+pf
#define lr pdp+pe+pf+pg+pa
#define ln pdp+pg+pa
#define lh pdp+pd+pe+pa
#define ly pdp+pb+pd
#define lu pdp+pg+pd
#define l__ pdp+pg+pb+pc+pe+pf
#define l___ l__-pg
#define l_1 255-pa
#define l_2 255-pa-pg
#define lj 255-(pe+pf+pa)
#define lwen 255-(pd+pe+pg+pb)
#define lall 0


#define lla 255-pa
#define llb 255-pb
#define llc 255-pc
#define lld 255-pd
#define lle 255-pe
#define llf 255-pf
#define llg 255-pg
#define lldp 255-pdp


//串行送出的位信息,目前是10位led顯示。
unsigned char code un_dig[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb};
//串行送出的簡訊息。
unsigned char code
un_disp[]={l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l_,lb,lc,l__,l___,lnul,lp,le,lj,ln,lf,la,lr,ld,lu,
ll,lh,lwen,lt,lla,llb,llc,lld,lle,llf,llg,lldp,lnul};


sbit d_clk=P0^0; //移位時鐘
sbit d_dat=P0^1; //移位數據
sbit d_st=P0^2; //移位鎖定


unsigned char dig; //位掃描計數器
unsigned char d[10]; //顯示緩衝

//送出8位串行數據
void out_disp(unsigned char dd) {
unsigned char i;
for (i=0;i<8;i++) {
if (dd&1) d_dat=1; else d_dat=0;
d_clk=0;
dd>>=1;
d_clk=1;
}
}
//控制小數點和閃爍,顯示數據|0x040表示有小數點;顯示數據|0x80表示閃爍。
void out_displ(unsigned char dd) {
if (dd>=0x80) {
if (s001>flash_time) {out_disp(0xff);return;}
}
dd&=0x7f;
if (dd>=0x40) {
dd=un_disp[dd&0x3f]^pdp;
} else dd=un_disp[dd];
out_disp(dd);
}

unsigned int s001; //閃爍時間參考
void int_t0(void) interrupt 1 {
unsigned char dd;
TL0=TL0+30;TH0=0xfb; //800
time++;
if ((++s001)>=800) s001=0;
// 顯示
if ((++dig)>4) dig=0;
d_st=0;
dd=d[dig+5];
out_displ(dd);
dd=d[dig];
out_displ(dd);
out_disp(un_dig[dig]);
d_st=1;
}
void main(void) {
unsigned char i;
TMOD=0x1;
TR0=ET0=1;
EA=1;
for (i=0;i<10;i++) d[i]=i; //display test
while (1) {}
}

相關焦點

  • PIC單片機C語言程序設計(4)
    在設計C 語言程序時,常常要根據某些條件以決定程序運行的流向,這時就需要if 語句來實現。任何if語句(包括else 部分),都可當作一條C 語句使用。  格式:if(表達式) 語句1  else 語句2  其中else 為選擇項;即可有、可無的。所以條件語句,可分為兩種;if 語句和if— else 語句。
  • PIC單片機C語言程序實例
    編者按:為了幫助具有PIC單片機彙編語言知識的技術人員或工程師,快速掌握利用C語言編寫PIC單片機程序的方法,本刊特推出《PIC單片機C語言程序設計》系列連載文章。丈中給出的C語言程序實例,均是可執行的,讀者可以放心引用。      一、彙編語言與C語言      早期的單片機程序多採用彙編語言編寫。
  • PIC單片機C語言程序設計(5)
    在《電子製作》2009年第10期,《PIC單片機C語言程序(1)》的延時函數中,我們已用過後綴運算符i++,大家可以從中體會其用法。  (2)邏輯運算符。  邏輯運算符是基本運算符中的一種。邏輯運算符有:與「&&」、或「||" 、非「!」等3三種。  邏輯運算符&&、||為雙目(兩個量)運算符,!為單目運算符。
  • 基於C語言51單片機電子密碼鎖的設計與仿真
    電子密碼鎖通常使用ARM和單片機控制,單片機相對ARM實現較為簡單,功能較為完善,因此使用單片機控制較多。用單片機控制的窖碼鎖常使用彙編語言編寫程序,顯示器多數用。而本文所介紹的電子密獁鎖使用移植性及可讀性強的高級語言C語言編寫,便於修改和增減功能蚤同時採用顯示清楚數碼管,功率消耗小而且壽命長的 液晶顯示器,顯示更加直觀,使用更加方便。
  • 基於C語言STC89C52單片機電子密碼鎖的設計與仿真
    它採用高可靠性的STC89C52單片機來實現開鎖和密碼的識別,採用具備I2C總線接口的E2PROM晶片來完成密碼的存儲,通過1602液晶顯示器提示程序運行狀態和使用步驟,利用蜂鳴器模擬報警,發光二極體模擬鎖的開關。該系統用C語言編寫程序,與彙編語言相比具備更好的移植性和可讀性,便於修改和增減功能。
  • 單片機教程:PIC單片機C語言程序設計(五)
    接前文:單片機教程:PIC單片機C語言程序設計(四)   九、C語言的運算符   C語言提供了30多個運算符,範圍很大,應用廣。  在《PIC單片機C語言程序(一)》的延時函數中,我們已用過後綴運算符i++,大家可以從中體會其用法。  (2)邏輯運算符。  邏輯運算符是基本運算符中的一種。邏輯運算符有:與「&&」、或「||「 、非「!」等3三種。  邏輯運算符&&、||為雙目(兩個量)運算符,!為單目運算符。
  • PIC單片機C語言程序設計(2)
    1.C語言的標識符  所謂標識符,實際上是一些由程序編寫者自定義的名稱,類似於PIC單片機彙編語言中給寄存器(RAM)的命名。,程式設計師編寫C程序時,可用關鍵字來對所用函數參數進行說明、定義一些物理量,它們是C語言語句的重要組成部分,有的還直接組成簡單語句。因此,用戶是不能將此類標識符(關鍵字)作為自定義標識符使用的。  C語言的關鍵字分為三類,即數據類、程序控制類和預處理類,如表1所示。
  • 單片機編程軟體大佬:明確單片機編程軟體編寫單片機程序步驟
    單片機用什麼軟體編程?單片機開發中除必要的硬體外,同樣離不開軟體,我們寫的彙編語言源程序要變為CPU可以執行的機器碼有兩種方法,一種是手工彙編,另一種是機器彙編,目前已極少使用手工彙編的方法了。機器彙編是通過彙編軟體將源程序變為機器碼,用於MCS-51單片機的彙編軟體有早期的A51,隨著單片機開發技術的不斷發展,從普遍使用彙編語言到逐漸使用高級語言開發,單片機的開發軟體也在不斷發展,Keil軟體是目前最流行開發MCS-51系列單片機的軟體,這從近年來各仿真機廠商紛紛宣布全面支持Keil即可看出。
  • 單片機c語言教程:C51循環語句
    這段程序的意思是在程序開始處用標識符「start:」標識,表示程序這是程序的開始,「end:」標識程序的 結束,標識符的定義應遵循前面所講的標識符定義原則,不能用 C 的關鍵字也不能和其它變 量和函數名相同,不然就會出錯了。程序執行 a++,a 的值加 1,當 a 等於 10 時程序會跳到 end 標識處結束程序,不然跳回到 start 標識處繼續 a++,直到 a 等於 10。
  • 寫出高效優美的單片機C語言代碼
    程序能跑起來並不見得你的代碼就是很好的c代碼了,衡量代碼的好壞應該從以下幾個方面來看1,代碼穩定,沒有隱患。下面發一些我在網上看到的技巧和自己的一些經驗來和大家分享;1、如果可以的話少用庫函數,便於不同的mcu和編譯器間的移植2、選擇合適的算法和數據結構應該熟悉算法語言,知道各種算法的優缺點,具體資料請參見相應的參考資料,有很多計算機書籍上都有介紹。
  • 【愛找茬】都是C語言,單片機C語言和普通的C語言究竟有什麼差異呢?
    儘管C語言提供了許多低級處理的功能,但仍然保持著良好跨平臺的特性,以一個標準規格寫出的C語言程序可在許多電腦平臺上進行編譯,甚至包含一些嵌入式處理器(單片機或稱MCU)以及超級電腦等作業平臺。 C語言是一門面向過程的計算機程式語言,與C++,Java等面向對象的程式語言有所不同。
  • CRC校驗碼在單片機中的程序實現的求取
    由單片機嵌入式系統與微機組成的工業檢測和數據採集系統中,計算機與單片機之間經常需要進行數據通信。在數字通信過程中,幹擾有可能使接收到的二進位數和發送的不一致,造成「0」和「1」互變的差錯。一個實用的通信系統必需能發現這種差錯,並加以糾正或給出重新發送信息。CRC(CyclICRedundancy Code循環冗餘碼),也稱多項式編碼。
  • S12單片機模塊應用及程序下載調試
    清華大學Freescale單片機/DSP應用開發研究中心  安鵬 馬偉摘 要:本文對邀請賽選用的主控晶片MC9S12DG128單片機的一些外圍接口模塊作了介紹,包括功能上的描述和例程及初始化的過程,對一些參賽隊伍中遇到的
  • 單片機的一些常識
    從數據存儲類型來說,8051系列有片內、片外程序存儲器,片內、片外數據存儲器,片內程序存儲器還分直接尋址區和間接尋址類型,分別對應code、data、xdata、idata以及根據51系列特點而設定的pdata類型,使用不同的存儲器,將使程序執行效率不同,在編寫C51程序時,最好指定變量的存儲類型,這樣將有利於提高程序執行效率
  • 基於單片機的記憶杯墊
    作為單片機系統來說,其實就是DS18B20和eeprom的應用,國產的stc單片機大多數都自帶了一定大小的eeprom,這就給設計者帶來了極大的方便。為了讓電路更加簡潔,這次選用的是STC11F04E的1T單片機,具備4K的程序存儲空間和1K的eeprom空間,20管腳的封裝設計大大減小了PCB面積。下面就是原理圖:
  • 單片機C語言程序設計:單只數碼管循環顯示 0~9
    /* 名稱:單只數碼管循環顯示 0~9說明:主程序中的循環語句反覆將 0~9 的段碼送至 P0 口,使數字 0~9 循環顯示uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//延時void DelayMS(uint x){uchar t;while(x--) for(t=0;t120;t++);}//主程序
  • 51系列單片機學習5—C編程程序語句
    在 C 中是有不少的括號,如{},[],()等,確實會讓一些初入門的朋友不解。在 VB 等一些語言中同一個()號會有不一樣的作用,它能用於組合若干條語句形成功能塊,能用做數組的下標等,而在 C 中括號的分工較為明顯,{}號是用於將若干條語句組合在一起形成一種功能塊,這種由若干條語句組合而成的語句就叫複合語句。複合語句之間用{}分隔,而它內部的各條語句還是需要以分號「;」 結束。
  • 程序的思考(從單片機到PC)
    如果將作業系統看作是在處理器上跑的一個很大的裸機程序(就是直接在硬體上跑的程序,因為作業系統就是直接跑在CPU上的,這樣看待是可以的,不過這個裸機程序功能很多,很強大),那麼作業系統的啟動很像MCU程序的啟動。前者有一個很大的初始化程序完成很複雜的初始化,後者有一段不長的彙編代碼完成一些簡單的初始化。這一點看,它們在流程上是很相似的。如果是系統上的程序啟動呢?它們是由系統來決定的。
  • 單片機兩級中斷嵌套的示例C程序
    單片機兩級中斷嵌套的示例C程序本文引用地址:http://www.eepw.com.cn/article/201611/320293.htm
  • 結合單片機學習板學習c語言之流水燈製作--intrins.h頭文件
    本文引用地址:http://www.eepw.com.cn/article/201608/294948.htm  源程序:  /*本程序結合STC89C51使用,晶振12M,中間用到串口中斷子程序是利用STC單片機的自定義ISP下載功能,自定義下載命令是FEH,關於自定義下載請參考《用51單片機就用STC51,手把手教你STC51的ISP