用51单片机编写个小程序

用51单片机编写个小程序,第1张

#include <reg52h>

#include "delayh"

#include "lcd1602h"

sbit SCK = P2^0;//sbit定义单片机的特殊功能寄存器变量

sbit SDA = P2^1;

bit ack = 0;//bit定义变量

void iic_start()

{

SDA = 1;

SCK = 1;

delay_us(1);

SDA = 0;

delay_us(1);

SCK = 0;//钳住总线,等待下次使用

}

void icc_stop()

{

SDA = 0;

SCK = 1;

delay_us(1);

SDA = 1;

delay_us(1);

SCK = 0;//钳住总线,等待下次使用

}

void iic_send_byte(unsigned char byte)

{

unsigned char i;

for(i = 0;i<8;i++)

{

SDA = byte & 0x80;//非0为1

SCK = 1;

delay_us(1);

SCK = 0;

byte <<=1;//左移一位

}

SDA = 1;

SCK = 1;

delay_us(1);

if(0 == SDA)//有应答

ack = 0;

else //无应答

ack =1;

SCK = 0;//钳住总线,等待下次使用

}

unsigned char iic_rcv_byte()

{

unsigned char i,temp;

SDA = 1;

for(i = 0;i < 8;i ++)

{

SCK = 0;

delay_us(1);

SCK = 1;

delay_us(1);

temp <<= 1;

if(SDA)

temp = temp+ 1;

}

SCK = 0;

return temp;

}

void iic_ack()

{

SDA = 0;

SCK = 1;

delay_us(1);

SCK = 0;

}

void iic_noack()

{

SDA = 1;

SCK = 1;

delay_us(1);

SCK = 0;

}

void AT_send_str(unsigned char deviceaddr,unsigned char romaddr,unsigned char s,unsigned char num)

{

unsigned char i;

iic_start();

iic_send_byte(deviceaddr);

if(ack == 1)

return;

iic_send_byte(romaddr);

if(ack == 1)

return;

for(i = 0;i < num; i ++)

{

iic_send_byte(s);

if(ack == 1)

return;

s++;

}

icc_stop();

}

void AT_rcv_str(unsigned char deviceaddr,unsigned char romaddr,unsigned char s,unsigned char num )

{

unsigned char i;

//SDA = 1;

iic_start();

iic_send_byte(deviceaddr);

if(ack == 1)

return;

iic_send_byte(romaddr);

if(ack == 1)

return;

iic_start();

iic_send_byte(deviceaddr + 1);

if(ack == 1)

return;

for(i = 0;i < num - 1; i++)

{

s = iic_rcv_byte();

iic_ack();//

s++;

}

s = iic_rcv_byte();

iic_noack();

icc_stop();

}

void main()

{

unsigned char i;

unsigned char testbuf[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,16,17,18,19};

unsigned char rcvbuf[20];

lcd_init();

AT_send_str(0xae,0,testbuf,10);

delay_ms(200);

AT_rcv_str(0xae,0,rcvbuf,10);

for(i = 0;i < 10; i++)

{

display_lcd_char(i,0,rcvbuf[i]+0x30);

}

while(1);

}

先在KEIL中编译生成HEX文件

(如果编译完了目录内没有找到HEX文件,在项目设置里,C51项中,勾上生成HEX文件选择)

再用COM51来烧。

(这个参照软件说,较简单。一般先载入HEX文件再点个AUTO就可以了)

流水灯就是51单片机控制led灯依次点亮的控制方式。具体程序如下:

ORG 0000H ;复位启动

AJMP START ;

ORG 001BH ;T1中断

AJMP T1INT ;

;定义变量========================

YSJS EQU 30H;延时计数器

LED EQU 31H;LED控制缓冲器

;主程序==========================

START: MOV LED,#0FEH ;初始化数据

MOV YSJS,#0 ;

MOV TMOD,#10H ;定时器1工作于方式1,16位定时器

MOV TL1,#0B0H ;设置定时初值

MOV TH1,#3CH ;定时时间=50mS

SETB ET1 ;使能定时器1中断

SETB TR1 ;启动定时器1

SETB EA ;开总中断

MOV P1,LED ;初始化流水灯

LOOP: JMP LOOP ;循环等待中断

T1INT: PUSH PSW ;定时器1中断程序

PUSH ACC ;保护现场

MOV TH1,#3CH ;定时时间=50mS

MOV TL1,#0B0H ;

INC YSJS ;

PUSH ACC ;保护ACC

MOV A,YSJI ;

CJNE A,#2,QT1 ;50mS2=100mS

MOV P1,LED ;

MOV A,LED ;

RL A ;累加器A的值循环左移1位

MOV LED,A ;

MOV YSJS,#0 ;

QT1: POP ACC ;恢复现场

POP PSW ;

RETI ;返回主程序

END ;汇编程序结束

扩展资料:

实现流水灯的三个方法:

第一种,总线方法实现流水灯。这是一种比较笨但又最易理解的方法,采用顺序程序结构,用位指令控制P1口的每一个位输出高低电平,加上延时函数,即可控制每个LED灯的亮灭。

第二种,移位方法实现流水灯采用循环程序结构编程。首先在程序开始给P10口送一个低电平,其它位为高。然后延时一段时间再让低电平往高位移动,这样就实现“流水”的效果了。

第三种,库函数实现流水灯。利用左移函数进行。

#include <AT89X51H>

unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; //定义显示用的段码

unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义显示用的位码

unsigned char dispbuf[8]={0,0,16,0,0,16,0,0}; //定义显示缓冲区

unsigned char dispbitcnt; //定义显示的位

unsigned char second; //定义秒

unsigned char minite; //定义分钟

unsigned char hour;//定义小时

unsigned int tcnt;//定义定时累加器

unsigned char mstcnt;//定义毫秒累加器

unsigned char i,j;

void main(void) //主函数

{

TMOD=0x02; //设置定时器工作模式

TH0=0x06; //设置初值

TL0=0x06;

TR0=1; //开定时器

ET0=1; //开定时器中断

EA=1; //开总中断

while(1)

{

if(P0_0==0) //判断P00口的按键是否按下

{

for(i=5;i>0;i--)

for(j=248;j>0;j--);//延时消抖

if (P0_0==0) //判断按键真的按下了

{

second++; //秒加1

if(second==60) //秒加到60?

{

second=0; //秒清零

}

dispbuf[0]=second%10; //取秒的个位放在显示缓冲

dispbuf[1]=second/10; //取秒的十位放在显示缓冲

while(P0_0==0); //等待,知道按键松开

}

}

if(P0_1==0) //p01的按键按下,设置分钟,请参考秒的程序,一样的

{

for(i=5;i>0;i--)

for(j=248;j>0;j--);

if(P0_1==0)

{

minite++;

if(minite==60)

{

minite=0;

}

dispbuf[3]=minite%10;

dispbuf[4]=minite/10;

while(P0_1==0);

}

}

if(P0_2==0) //p02的按键按下,设置小时,请参考秒的程序,一样的

{

for(i=5;i>0;i--)

for(j=248;j>0;j--);

if(P0_2==0)

{

hour++;

if(hour==24)

{

hour=0;

}

dispbuf[6]=hour%10;

dispbuf[7]=hour/10;

while(P0_2==0);

}

}

}

}

void t0(void) interrupt 1 using 0 //定时器中断函数

{

mstcnt++; //累加器加一

if(mstcnt==8) //计时满8毫秒?

{

mstcnt=0; //累加器清零

P1=dispcode[dispbuf[dispbitcnt]]; //送显示段码

P3=dispbitcode[dispbitcnt]; //送显示位码

dispbitcnt++; //显示位加1

if(dispbitcnt==8) //8位都显示完了?

{

dispbitcnt=0; //从第一位开始显示

}

}

tcnt++; //累加器加一

if(tcnt==4000) //记满1秒

{

tcnt=0; //累加器清零

second++; //秒加一

if(second==60) //秒满60?

{

second=0; //秒清零

minite++; //分钟加一

if(minite==60) //分钟满60

{

minite=0; //分钟清零

hour++; //小时加1

if(hour==24) //小时满24

{

hour=0; //小时清零

}

}

}

dispbuf[0]=second%10; //将时分秒的个位与十位分开,装在显示区

dispbuf[1]=second/10;

dispbuf[3]=minite%10;

dispbuf[4]=minite/10;

dispbuf[6]=hour%10;

dispbuf[7]=hour/10;

}

}

其实这个程序不难,仔细想想,有不懂的再问我吧

以上就是关于用51单片机编写个小程序全部的内容,包括:用51单片机编写个小程序、用keil如何给51单片机烧写程序、51单片机中如何用汇编语言编写流水灯等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9285587.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存