单片机c语言编程代码?单片机编程
很多朋友对于单片机c语言编程代码和单片机编程不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!
如何写出高效的单片机C语言程序代码
由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法
与之比较的。PC机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。
对于单片机来说就截然不同了,一般的单片机的Flash和Ram的资源是以KB来衡量的,可想而知,单片
机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须
遵循以下几点进行优化:
1.使用尽量小的数据类型
能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变
量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。当然,在定义变
量后不要超过变量的作用范围,如果超过变量的范围赋值,C编译器并不报错,但程序运行结果却错了,
而且这样的错误很难发现。
2.使用自加、自减指令
通常使用自加、自减指令和复合赋值表达式(如a-=1及a+=1等)都能够生成高质量的
程序代码,编译器通常都能够生成inc和dec之类的指令,而使用a=a+1或a=a-1之类
的指令,有很多C编译器都会生成二到三个字节的指令。
3.减少运算的强度
可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。
(1)求余运算
N= N%8可以改为N= N&7
说明:位操作只需一个指令周期即可完成,而大部分的C编译器的“%”运算均是调用子程序来
完成,代码长、执行速度慢。通常,只要求是求2n方的余数,均可使用位操作的方法来代替。
(2)平方运算
N=Pow(3,2)可以改为N=3*3
说明:在有内置硬件乘法器的单片机中(如51系列),乘法运算比求平方运算快得多,因为浮点数
的求平方是通过调用子程序来实现的,乘法运算的子程序比平方运算的子程序代码短,执行速度快。
(3)用位移代替乘法除法
N=M*8可以改为N=M<<3
N=M/8可以改为N=M>>3
说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移
的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子
程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果。如N=M*9
可以改为N=(M<<3)+M;
(4)自加自减的区别
例如我们平时使用的延时函数都是通过采用自加的方式来实现。
void DelayNms(UINT16 t)
{
UINT16 i,j;
for(i=0;i<t;i++)
for(j=0;i<1000;j++)
}
可以改为
void DelayNms(UINT16 t)
{
UINT16 i,j;
for(i=t;i>=0;i--)
for(j=1000;i>=0;j--)
}
说明:两个函数的延时效果相似,但几乎所有的C编译对后一种函数生成的代码均比前一种代码少1~3
个字节,因为几乎所有的MCU均有为0转移的指令,采用后一种方式能够生成这类指令。
4. while与do...while的区别
void DelayNus(UINT16 t)
{
while(t--)
{
NOP();
}
}
可以改为
void DelayNus(UINT16 t)
{
do
{
NOP();
}while(--t)
}
说明:使用do…while循环编译后生成的代码的长度短于while循环。
5. register关键字
void UARTPrintfString(INT8*str)
{
while(*str&& str)
{
UARTSendByte(*str++)
}
}
可以改为
void UARTPrintfString(INT8*str)
{
register INT8*pstr=str;
while(*pstr&& pstr)
{
UARTSendByte(*pstr++)
}
}
说明:在声明局部变量的时候可以使用register关键字。这就使得编译器把变量放入一个多用途的寄存
器中,而不是在堆栈中,合理使用这种方法可以提高执行速度。函数调用越是频繁,越是可能提高代码的
速度,注意register关键字只是建议编译器而已。
6. volatile关键字
volatile总是与优化有关,编译器有一种技术叫做数据流分析,分析程序中的变量在哪里赋值、在
哪里使用、在哪里失效,分析结果可以用于常量合并,常量传播等优化,进一步可以死代码消除。一般来
说,volatile关键字只用在以下三种情况:
a)中断服务函数中修改的供其它程序检测的变量需要加volatile(参考本书高级实验程序)
b)多任务环境下各任务间共享的标志应该加volatile
c)存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义
总之,volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素
更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码
就不再进行优化,从而可以提供对特殊地址的稳定访问。
51单片机C语言编程
// 51单片机C语言编程,这个时钟+秒表可以参考一下。
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit qingling=P1^0;//清零
sbit tiaofen=P1^1;//调分
sbit tiaoshi=P1^2;//调时
sbit sounder=P1^7;//naozhong
uint a,b;
uchar hour,minu,sec,//时钟
hour0,minu0,sec0,//秒表
hour1,minu1,sec1;
h1,h2,m1,m2,s1,s2,//显示位
k,s;//状态转换标志
uchar code select[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/*****************函数声明***********************/
void keyscan();
void init();
void delay(uchar z);
void display(uchar,uchar,uchar);
void sounde();
/*****************主函数*************************/
void main()
{
init();
while(1)
{
while(TR1)
{
keyscan();//扫描函数
while(s==1)//s是状态标志,当s=0时,闹钟取消。s=1时,设定闹钟时间(也是通过调时,调分函数);
{//s=2时,闹钟工作,时间与设定时刻一致时,闹钟响(一分钟后自动关闭,可手动关闭)。再次切换,s=0.
keyscan();//s状态切换(0-》1-》2-》0)通过外部中断1实现。
display(hour1,minu1,sec1);//闹钟时刻显示
}
display(hour0,minu0,sec0);//时钟表显示
while(k)/*k是秒表状态(0-》1-》2-》0)通过外部中断0实现。0秒表关;1秒表从零计时;2秒表停,显示计时时间*/
{
display(hour,minu,sec);//秒表显示
}
}
}
}
/*****************初始化函数***********************/
void init()
{
a=0;
b=0;
k=0;
s=0;
hour0=0;
minu0=0;
sec0=0;
hour=0;
minu=0;
sec=0;
hour1=0;
minu1=0;
sec1=0;
TMOD=0x11;//定时器0,1工作于方式1;赋初值
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
EX0=1;//秒表中断
EX1=1;//闹钟设定中断
ET0=1;
ET1=1;
IT0=1;//边沿触发方式
IT1=1;
PX0=1;
PX1=1;
TR0=0;//初始,秒表不工作
TR1=1;//时钟一开始工作
}
/*****************定时器0中断*************/
void timer0_int() interrupt 1//秒表
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
a++;
if(a==2)
{
a=0;
sec++;
if(sec==100)
{
sec=0;//毫秒级
minu++;
if(minu==60)
{
minu=0;//秒
hour++;
if(hour==60)//分
{
hour=0;
}
}
}
}
}
/*************外部中断0中断函数************/
void ex0_int() interrupt 0
{
k++;
if(k==3)
k=0;
if(k==1)
{
TR0=~TR0;
if(TR0==1)
{
hour=0;
minu=0;
sec=0;
}
}
if(k==2)
{
TR0=~TR0;
}
}
/*************外部中断1中断函数************/
void ex1_int() interrupt 2
{
s++;
if(s==3)
s=0;
}
/*************定时器1中断****************/
void timer1_int() interrupt 3//控制时钟工作
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(s==2)
{
if(hour1==hour0&& minu0==minu1)
sounde();
}
b++;
if(b==20)
{
b=0;
sec0++;
if(sec0==60)
{
sec0=0;
minu0++;
if(minu0==60)
{
minu0=0;
hour0++;
if(hour0==24)
hour0=0;
}
}
}
}
/*************键盘扫描****************/
void keyscan()
{
if(s==1)
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec1=0;
minu1=0;
hour1=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu1++;
if(minu1==60)
{
minu1=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour1++;
if(hour1==24)
{
hour1=0;
}
while(!tiaoshi);
}
}
else//调整时钟时间
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec0=0;
minu0=0;
hour0=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu0++;
if(minu0==60)
{
minu0=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour0++;
if(hour0==24)
{
hour0=0;
}
while(!tiaoshi);
}
}
}
/*************显示函数****************/
void display(uchar hour,uchar minu,uchar sec)
{
h1=hour/10;
h2=hour%10;
m1=minu/10;
m2=minu%10;
s1=sec/10;
s2=sec%10;
P0=0xff;
P2=table[h1];
P0=select[7];
delay(5);
P0=0xff;
P2=table[h2];
P0=select[6];
delay(5);
P0=0xff;
P2=0x40;;
P0=select[5];
delay(5);
P0=0xff;
P2=table[m1];
P0=select[4];
delay(5);
P0=0xff;
P2=table[m2];
P0=select[3];
delay(5);
P0=0xff;
P2=0x40;
P0=select[2];
delay(5);
P0=0xff;
P2=table[s1];
P0=select[1];
delay(5);
P0=0xff;
P2=table[s2];
P0=select[0];
delay(5);
}
/*************闹钟函数****************/
void sounde()
{
sounder=~sounder;
}
/*************延时函数****************/
void delay(uchar z)
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
C语言怎么写进单片机
1:先把写好的C语言进行编译,生成*.hex或*.bin文件,推荐用keil C。
然后:
1:根据你单片机的型号买一个烧录器,与PC连接好后,把单片机放在烧录器的插座上(看你的单片机封装,新手尽量用DIP的),根据烧录器软件提示把上述文件烧到单片机里,缺点:价格较高
2:用下载线,用法与烧录器差不多,缺点:比较麻烦,要有一定经验。
3:用学习板,一般学习板上面的单片机可以直接在线烧录(如STC,SST系列的单片机),也就是说单片机不用拆下来,板子上做好了烧录电路,可以在板子上烧录,然后就可以直接验证了。
4:自已做一个,用STC的单片机,只要用一个RS232的转换电路(一片232IC,几个电解电容就行了),STC的单片机可以通过串口烧录程序,具体参见STC官网或其DATASHEET,有详细介绍。缺点:要一定动手能力
推荐新手用第3方法,可以很快上手。
单片机c语言编程代码和单片机编程的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!