173 2438 5004
KEROS加密芯片——品牌直销 | 免费样品 | 技术支持
当前位置:网站首页 > 资讯中心 正文 资讯中心

8位单片机如何编写程序

htxw 2023-03-14 资讯中心 20 ℃

51单片机显示八位数码管的C语言程序

1、最开始,我们先打开keil。

2、接着,我们要定义好库函数,想要实现动态数码灯,这个步骤是很重要的。

3、接着,我们加上一条循环语句。

4、最后,我们把先前定义的延时语句delayms写好。

5、最后,点击这里进行编译,生成一个hex文件。

6、如果这里无错误警告的话,就说明我们的程序写对了,那我们就可以点亮动态数码管了。

一般8位PIC单片机使用C语言还是汇编语言编程,好像编译器不是支持所有类型的单片机

PIC单片机的C语言编译器是分类支持各类PIC单片机的。

一般做工业产品的公司大多用汇编来编写程序,原因有:

1:pic的8位单片机一般ROM和RAM都相对较小,而现在的PIC的C编译器在优化方面做的不是很好,简单的一个C语句编译器能编出很多行汇编代码。所以有些开发人员认为用c还不如直接用汇编写。

2:因为PIC的C编译器不是免费的,破解版的又存在一些逻辑漏洞什么的。而用pic单片机应用的大多是一些需要稳定性极高的控制场合,所以很多开发公司都干脆直接使用汇编来写。

8位单片机PID控制PWM的算法如何实现,C语言计算?

PID控制在8位单片机中仍然有广泛的应用,比如温度控制,利用比例、积分、微分补偿来做恒温补偿控制,当然由于有这些数学处理,用C语言相对方便一些,以下是一个具体的实例。

#includereg51.h

#includeintrins.h

#includemath.h

#includestring.h

struct PID {

unsigned int SetPoint; // 设定目标 Desired Value

unsigned int Proportion; // 比例常数 Proportional Const

unsigned int Integral; // 积分常数 Integral Const

unsigned int Derivative; // 微分常数 Derivative Const

unsigned int LastError; // Error[-1]

unsigned int PrevError; // Error[-2]

unsigned int SumError; // Sums of Errors

};

struct PID spid; // PID Control Structure

unsigned int rout; // PID Response (Output)

unsigned int rin; // PID Feedback (Input)

sbit data1=P1^0;

sbit clk=P1^1;

sbit plus=P2^0;

sbit subs=P2^1;

sbit stop=P2^2;

sbit output=P3^4;

sbit DQ=P3^3;

unsigned char flag,flag_1=0;

unsigned char high_time,low_time,count=0;//占空比调节参数

unsigned char set_temper=35;

unsigned char temper;

unsigned char i;

unsigned char j=0;

unsigned int s;

/***********************************************************

延时子程序,延时时间以12M晶振为准,延时时间为30us×time

***********************************************************/

void delay(unsigned char time)

{

   unsigned char m,n;

   for(n=0;ntime;n++)

   for(m=0;m2;m++){}

}

/***********************************************************

写一位数据子程序

***********************************************************/

void write_bit(unsigned char bitval)

{

EA=0;

DQ=0; /*拉低DQ以开始一个写时序*/

if(bitval==1)

{

_nop_();

DQ=1; /*如要写1,则将总线置高*/

}

delay(5); /*延时90us供DA18B20采样*/

DQ=1; /*释放DQ总线*/

_nop_();

_nop_();

EA=1;

}

/***********************************************************

写一字节数据子程序

***********************************************************/

void write_byte(unsigned char val)

{

   unsigned char i;

  unsigned char temp;

  EA=0;

  TR0=0;

for(i=0;i8;i++) /*写一字节数据,一次写一位*/

{

temp=vali; /*移位操作,将本次要写的位移到最低位*/

temp=temp1;

write_bit(temp); /*向总线写该位*/

}

delay(7); /*延时120us后*/

// TR0=1;

EA=1;

}

/***********************************************************

读一位数据子程序

***********************************************************/

unsigned char read_bit()

{

unsigned char i,value_bit;

EA=0;

DQ=0; /*拉低DQ,开始读时序*/

_nop_();

_nop_();

DQ=1; /*释放总线*/

for(i=0;i2;i++){}

value_bit=DQ;

EA=1;

return(value_bit);

}

/***********************************************************

读一字节数据子程序

***********************************************************/

unsigned char read_byte()

{

unsigned char i,value=0;

EA=0;

for(i=0;i8;i++)

{

if(read_bit()) /*读一字节数据,一个时序中读一次,并作移位处理*/

value|=0x01i;

delay(4); /*延时80us以完成此次都时序,之后再读下一数据*/

}

EA=1;

return(value);

}

/***********************************************************

复位子程序

***********************************************************/

unsigned char reset()

{

unsigned char presence;

EA=0;

DQ=0; /*拉低DQ总线开始复位*/

delay(30); /*保持低电平480us*/

DQ=1; /*释放总线*/

delay(3);

presence=DQ; /*获取应答信号*/

delay(28); /*延时以完成整个时序*/

EA=1;

return(presence); /*返回应答信号,有芯片应答返回0,无芯片则返回1*/

}

/***********************************************************

获取温度子程序

***********************************************************/

void get_temper()

{

unsigned char i,j;

do

{

 i=reset(); /*复位*/

}  while(i!=0); /*1为无反馈信号*/

   i=0xcc; /*发送设备定位命令*/

 write_byte(i);

 i=0x44; /*发送开始转换命令*/

 write_byte(i);

 delay(180); /*延时*/

do

{

 i=reset(); /*复位*/

}  while(i!=0);

 i=0xcc; /*设备定位*/

 write_byte(i);

 i=0xbe; /*读出缓冲区内容*/

 write_byte(i);

 j=read_byte();  

 i=read_byte();

 i=(i4)0x7f;

 s=(unsigned int)(j0x0f);     //得到小数部分

 s=(s*100)/16;

 j=j4;

 temper=i|j; /*获取的温度放在temper中*/

}

/*====================================================================================================

Initialize PID Structure

=====================================================================================================*/

void PIDInit (struct PID *pp)

{

memset ( pp,0,sizeof(struct PID));    //全部初始化为0

}

/*====================================================================================================

PID计算部分

=====================================================================================================*/

unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )

{

unsigned int dError,Error;

Error = pp-SetPoint - NextPoint;          // 偏差  

pp-SumError += Error;                     // 积分  

dError = pp-LastError - pp-PrevError;    // 当前微分

pp-PrevError = pp-LastError;  

pp-LastError = Error;

return (pp-Proportion * Error             // 比例项  

+ pp-Integral * pp-SumError              // 积分项

+ pp-Derivative * dError);                // 微分项

}

/***********************************************************

温度比较处理子程序

***********************************************************/

void compare_temper()

{

unsigned char i;

if(set_tempertemper)      //是否设置的温度大于实际温度

{

 if(set_temper-temper1)  //设置的温度比实际的温度是否是大于1度

{

 high_time=100;      //如果是,则全速加热

 low_time=0;

}

     else  //如果是在1度范围内,则运行PID计算

{

  for(i=0;i10;i++)

{

  get_temper();   //获取温度

   rin = s; // Read Input

  rout = PIDCalc ( spid,rin ); // Perform PID Interation

}

  if (high_time=100)

    high_time=(unsigned char)(rout/800);

  else

        high_time=100;

    low_time= (100-high_time);

}

}

else if(set_temper=temper)

{

 if(temper-set_temper0)

{

  high_time=0;

  low_time=100;

}

 else

{

   for(i=0;i10;i++)

 {

       get_temper();

       rin = s; // Read Input

   rout = PIDCalc ( spid,rin ); // Perform PID Interation

 }

   if (high_time100)

    high_time=(unsigned char)(rout/10000);

     else

    high_time=0;

    low_time= (100-high_time);

}

}

// else

// {}

}

/*****************************************************

T0中断服务子程序,用于控制电平的翻转 ,40us*100=4ms周期

******************************************************/

void serve_T0() interrupt 1 using 1

{

if(++count=(high_time))

output=1;

else if(count=100)

{

output=0;

}

else

count=0;

TH0=0x2f;

TL0=0xe0;

}

/*****************************************************

串行口中断服务程序,用于上位机通讯

******************************************************/

void serve_sio() interrupt 4 using 2

{

/* EA=0;

RI=0;

i=SBUF;

if(i==2)

{

while(RI==0){}

RI=0;

set_temper=SBUF;

SBUF=0x02;

while(TI==0){}

TI=0;

}

else if(i==3)

{

TI=0;

SBUF=temper;

while(TI==0){}

TI=0;

}

EA=1; */

}

void disp_1(unsigned char disp_num1[6])

{

unsigned char n,a,m;

for(n=0;n6;n++)

{

// k=disp_num1[n];

for(a=0;a8;a++)

{

   clk=0;

m=(disp_num1[n]1);

disp_num1[n]=disp_num1[n]1;

if(m==1)

 data1=1;

else

 data1=0;

 _nop_();

 clk=1;

 _nop_();

}

}

}

/*****************************************************

显示子程序

功能:将占空比温度转化为单个字符,显示占空比和测得到的温度

******************************************************/

void display()

{

unsigned char code number[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};

unsigned char disp_num[6];

unsigned int k,k1;

k=high_time;

k=k%1000;

k1=k/100;

if(k1==0)

disp_num[0]=0;

else

disp_num[0]=0x60;

k=k%100;

disp_num[1]=number[k/10];

disp_num[2]=number[k%10];

k=temper;

k=k%100;

disp_num[3]=number[k/10];

disp_num[4]=number[k%10]+1;

disp_num[5]=number[s/10];

disp_1(disp_num);

}

/***********************************************************

主程序

***********************************************************/

void main()

{

unsigned char z;

unsigned char a,b,flag_2=1,count1=0;

unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2};

TMOD=0x21;

TH0=0x2f;

TL0=0x40;

SCON=0x50;

PCON=0x00;

TH1=0xfd;

TL1=0xfd;

PS=1;

EA=1;

EX1=0;

ET0=1;

ES=1;

TR0=1;

TR1=1;

high_time=50;

low_time=50;

PIDInit ( spid );    // Initialize Structure

spid.Proportion = 10; // Set PID Coefficients  比例常数 Proportional Const

spid.Integral = 8;    //积分常数 Integral Const

spid.Derivative =6;   //微分常数 Derivative Const

spid.SetPoint = 100; // Set PID Setpoint 设定目标 Desired Value

while(1)

{

if(plus==0)

{

EA=0;

for(a=0;a5;a++)

for(b=0;b102;b++){}

if(plus==0)

{

set_temper++;

flag=0;

}

}

else if(subs==0)

{

for(a=0;a5;a++)

for(b=0;a102;b++){}

if(subs==0)

{

set_temper--;

flag=0;

}

}

else if(stop==0)

{

   for(a=0;a5;a++)

  for(b=0;b102;b++){}

  if(stop==0)

{

 flag=0;

 break;

}

 EA=1;

}

     get_temper();

 b=temper;

if(flag_2==1)

a=b;

if((abs(a-b))5)

temper=a;

else

temper=b;

a=temper;

flag_2=0;

if(++count130)

{

display();

count1=0;

}

compare_temper();

}

 TR0=0;

 z=1;

while(1)

{

  EA=0;

if(stop==0)

{

   for(a=0;a5;a++)

  for(b=0;b102;b++){}

  if(stop==0)

  disp_1(phil);

// break;

}

EA=1;

}

}

51单片机8位流水灯程序怎么写

以P1口的8位共阳极LED为例,

初始化:

sbit P1_0=P1^0;

sbit P1_1=P1^1;

sbit P1_2=P1^2;

sbit P1_3=P1^3;

sbit P1_4=P1^4;

sbit P1_5=P1^5;

sbit P1_6=P1^6;

sbit P1_7=P1^7;

delay函数:

void delay(int x)

{

int a,b;

for(a=0;ax;a++)

{

for(b=0;b10000;b++);

}

}

主程序

void main()

while(1)

{

P1_0=1;

delay(1000);

P1_0=0;

delay(1000);

P1_1=1;

delay(1000);

P1_1=0;

delay(1000);

//以此类推至P1_7

}

如何用单片机编写一个八位循环计数器程序

x0为启动按钮,x1为停止按钮。y0~y7为8盏灯。程序在按下启动按钮后,灯1先亮,1秒(T0延时)后灭,1秒后(T1延时)灯2亮,依次循环。当按下x1后,循环结束。

按下x0后,m0得电为1并自保持,此时1秒计时器T0计时,1秒后T0常开点闭合1秒计时器T1计时,再过1秒T1计时结束常闭点断开T0线圈,

T0失电复位并断开T0常开点,此时T1线圈也失电复位,T1常闭点又闭合,T0得电重复上述计时过程。

第二个程序块:

当M0为1时,在T0触点的上升沿来时k3M10这个二进制数乘以2再写入k3M10中。

K3M10代表M10~M21共12个辅助继电器的组合,那么可以将K3M10看作是一个二进制数。程序未启动时,M10~M21均为0,那么这个二进制数为0;当程序启动时,在下一个程序块中利用了M0的上升沿置位M10,此时M10~M21为1,当T0触点的上升沿来时k3M10(此时为1)这个二进制数乘以2再写入k3M10中(写入后为2),2在二进制数中为10,此时M10失电,M11得电,可以认为M10把"1"交给了M11,以此类推。当第8个M17得电时,完成了一次循环。下一个T0上升沿来到时,M18得电,M17失电。此时下面的程序块利用了M18的上升沿重新置位M10并且将M18复位。这样程序又从M10得电开始循环下去了。

这个程序块的作用就是每次T0的上升沿来到时,“1”在M10~M17之间转移。

8位单片机如何编写程序的介绍就聊到这里吧,感谢您花时间阅读,谢谢。

本文标签:8位单片机如何编写程序

<