历史上的今天
今天是:2025年03月02日(星期日)
2020年03月02日 | 51单片机中断、串口通信综合程序
2020-03-02 来源:51hei
正在初学51的中断,定时器,串口等等,遇到很多瓶颈比如串口怎么发送变量的数值啦(加一个0x30就好),分享这个程序给初学者们啦
功能:
1. 开机以后,LED0和LED1实现0.5秒间隔闪烁2次,蜂鸣器同时鸣叫2次。
2. 之后,串口等待接收到一个字符'R',开始进入主循环体。
3. 主循环体中,LED0和LED1实现1秒间隔闪烁。
4. 串口接收到字符'D',回复LED当前状态和系统当前处于运行还是暂停状态,如果运行状态,收到字符'R',如果暂停状态,收到字符'P'。
5. 串口接收到字符'T',回复主循环体开始运行的时间和系统当前处于运行还是暂停状态,时间单位为秒,最大计数值65535,以每一位的ASCII码字符发送,最后加换行符。
6. 串口接收到其他字符,回复字符'W',且蜂鸣器高频率鸣叫2次。
7. 主循环体运行每分钟,蜂鸣器低频率鸣叫1次。
8. 开启INT0中断,按下S_INT0,可以暂停目前的程序运行,再次按下,可以继续运行,之前的所有都保持继续运行的状态,计数值也继续累加。暂停状态下, 依然可以响应串口的'D'和'T'的应答回复,具体暂停还是运行状态的解释,详见第4条要求。
9. 所有定时, 用T0方式1中断实现。
10. 串行口配置为方式1,4800波特率,中断接收,查询发送。
PS:定时器的初值为了方便是用晶振12HZ算的哦,想要精确延时的朋友记得换成11.0592算一下啦
用的STC89C52REC的迷你单片机
单片机源程序如下:
#include #include"main.h" void main() { init(); for(i=0; i<2; i++) { LED0 = 0; LED1 = 0; beep = 0; delay(25); LED0 = ~LED0; LED1 = ~LED1; beep = 1; delay(25); } while(1) { while(g_b_enter_flag) { if(LED0 == LED1) { LED0 = 0; LED1 = 1; delay(50); } LED0 = ~LED0; LED1 = ~LED1; delay(50); }//end of while(g_b_enter_flag) while(!g_b_enter_flag) { ; } }//end of while(1) } //按键中断子程序 void int0() interrupt 0 { g_b_enter_flag = ~g_b_enter_flag;//暂停和继续的切换 } //定时器中断子程序 void Timer0() interrupt 1 using 1 { TH0 = 0xB1; //重新加载初值 TL0 = 0xE0; g_i_cnt++; if(g_b_enter_flag) { g_i_20ms_time++; //记录主循环运行时间 } if(g_i_20ms_time>50) //主程序运行1s { g_i_1s_time++; g_i_totaltime++; g_i_20ms_time = 0; } if(g_i_1s_time>60) //运行一分钟 { beep = 0; cdelay(200); beep = 1; g_i_1s_time=0; } if(g_i_1s_time>65535)//最大计时值655353 { g_i_1s_time = 0; } } //精确延时 void delay(unsigned int z) { g_i_cnt=0; while(g_i_cnt ; } g_i_cnt=0; } //发送一个字符 void send(unsigned char byte) { SBUF=byte; while(!TI); TI=0; } //不精确延时 void cdelay(unsigned int k) { unsigned int x,y; for(x=0; x for(y=0;y<600;y++); } } //外部中断和定时器的初始化 void init() { i=0; g_b_R_flag=0;//判断是否是第一次发送R g_b_enter_flag=0; //判断是否进入主循环,0为否,1为是 g_i_cnt=0; //精确延时用 g_i_20ms_time=0; //一个等于20ms g_i_1s_time=0; //一个等于1s g_i_totaltime=0; //主程序运行总时间 EX0 = 1;//开外部中断0 IT0 = 0;//外部中断0低电平触发 ET0 = 1;//打开定时器0中断 TMOD |= 0X01; //定时器工作模式1,16位定时模式 TR0 = 1;//启动定时器0 TH0 = 0xB1; TL0 = 0xE0; //定时20ms ES = 1; //打开串口中断 SCON = 0x50;//配置串口为模式 1 REN = 1;//串口允许接收 TMOD |= 0x20;//定时器1,工作模式2 8位自动重装 TH1 = 0xFA; //波特率4800 TL1 = 0xFA; ET1 = 0; //禁止 T1 中断 TR1 = 1;//启动定时器1 EA = 1; //打开总中断 } //UART中断服务函数 void InterruptUART() interrupt 4 using 1 { if(RI)//判断接收是否完成 { RI = 0;//手动清零接收中断标志位 if((SBUF==0x52)&(g_b_R_flag==1)) { send('W'); beep=0; cdelay(60); beep=1; cdelay(60); beep=0; cdelay(60); beep=1; cdelay(60); } if(SBUF==0x52) //接受字母为R,开始进入主循环体 { g_b_enter_flag = 1; g_b_R_flag=1; } else if(SBUF==0x44)//接收字母为D,发送LED状态 { if(g_b_enter_flag) { send('R'); send('n'); if(LED0==1&&LED1==0) { send('C'); send('O'); send('n'); } else { send('O'); send('C'); send('n'); } } else {
史海拾趣
|
HTCAD是一套基于AutoCAD平台上开发的土方工程量计算绘图软件,针对各种复杂地形况,软件采用了方格网法计算土石方量。软件具有良好的交互性,界面友好,贴近设计人员的设计思路,能够在最短的时间内计算出土石方量。适用于工业设计院总图专业,规划 ...… 查看全部问答> |
|
1、储能电感。储能电感在工作频率下的Q值越大越好,很多人只注意到电感量,其实Q值的影响要大得多,电感量只要满足要求允许在很大范围内波动。 2、滤波电容。滤波电容的ESR和ESL是非常重要的参数,越低越好,仅追求容量是远远不够的,当然在满 ...… 查看全部问答> |
|
前几天发过一个电路,有噪声.但没人给解答.后来又重新用TDA2822做了一个麦克风放大的,用在对讲电路中,效果很好,没有一点噪声. 因为开始自己寻找这方面的电路找了很久,但照图弄出来效果都不理想.所以就想把自己的贴出来,给需要的同行一点帮助. 本电 ...… 查看全部问答> |
|
有一个问题有点疑惑,以前没弄过焊接开发板的事,现在想想要是想把模块芯片焊接到开发板上那么引脚该怎么连啊,比如我想连接编解码芯片到开发板上,用iic总线传输控制信号,spi接口传输数据,通用i/o口传一些中断等信号,那么这块芯片怎么和开发板 ...… 查看全部问答> |
|
小弟调用tcpmp的common.dll来做开发 Context_Init((tchar_t*)name, (tchar_t*)version, id, (tchar_t*)cmdline, application);   ...… 查看全部问答> |
|
我的意思是,用evc ide 直接连接 sdk 开发板(2410) 直接下载到板子上执行。 板子上已经用pb 4.2 编译的wince 下载完毕。 我目前只能evc ide 下载到 evc 的 模拟器上执行。 如何,让evc ide 连接 sdk (2410)直接执行呢? 需要配置什么?… 查看全部问答> |
|
请教S3C2440中的Uart串口地址问题:UART0的发送缓冲区地址为0X50000020,接收缓冲区地址为0X50000024,中间只相差4个字节,怎么来的64字节的FIFO缓冲区呢? 谢谢!… 查看全部问答> |




