实验目的
- 了解单片机串口通信基本原理
- 掌握串口中断与定时中断编写以及工作模式原理
- 掌握串口收发寄存器的使用
实验要求
- 通过电脑下发指令给单片机
- 若为 ‘0x01’ 指令,单片机将8位数码管全部显示为0
- 若为 ‘0x02’ 指令,8位数码管显示当前时间
- 每过一分钟,单片机向电脑报告当前时间
- 电脑可以下发指令设置时间
所用工具
- Keil uVision4 编译软件
- stc-isp 串口助手
- Proteus 8 仿真软件
- Configure Virtual Serial Port Driver 虚拟串口工具
具体实现代码
#include <reg51.h>
#include <string.h>
unsigned char segdata[10] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char bitdata[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
unsigned char tempdata[8];
unsigned char temp[18]={0};
unsigned int index=0;
unsigned char ch,biao;
unsigned char shi = 12;
unsigned char fen = 1;
unsigned char miao = 56;
unsigned char hour,min,sen;
unsigned char flag=0,flg=0,count=0;
static int a;
void delay_us(unsigned long i){
while(i--);
}
void display()
{
unsigned char i = 0;
for(;i<8;i++){
P2=bitdata[i];
P1 = tempdata[i];
delay_us(100);
}
}
void clean(){
unsigned char k;
for(k=0;k<index;k++){
temp[k]=0;
index=0;
}
}
int compared_head(char cmd_head[])
{
unsigned char m;
for(m=0;m<4;m++) {
if(!(temp[m+1]==cmd_head[m]))
{
return 0;
}
}
return 1;
}
int Compare_end(unsigned char start,unsigned char num,char end[])
{
unsigned char n;
for(n=0;n<num;n++)
{
if(!(temp[start+n]==end[n]))
{
return 0;
}
}
return 1;
}
int infodata(){
if(temp[0]=='$'){
if(compared_head("set:")){
if(temp[7]=='-'){
if(temp[10]=='-'){
if(Compare_end(13,5,"clock")){
return 1;
}
}}}}
return 0;
}
void uart_init()
{
SCON = 0x50;
TMOD |= 0x20;
PCON=0x00;
TH1 =TL1=0xfd;
TR1 = 1;
ET1=0;
EA = 1;
ES = 1;
}
void uart_send_byte(unsigned char byte)
{
SBUF = byte;
while(!TI);
TI = 0;
}
void uart_send_str(unsigned char *s)
{
while(*s != '\0')
{
uart_send_byte(*s);
s++;
}
}
void uart_isr() interrupt 4
{
if(RI)
{
ch=SBUF;
if(ch!='#'){
temp[index++] = ch;
}else{
index=0;
biao=1;
}
RI = 0;
}
if(TI){
TI=0;
}
}
void timer0_init(void)
{
EA = 1;
TMOD |= 0x01;
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
ET0 = 1;
TR0 = 1;
}
void timer0_isr() interrupt 1
{
TH0 = (65535 - 50000)/256;
TL0= (65535 - 50000)%256;
a++;
if(a==20)
{
a = 0;
miao++;
count++;
if(count==60){
count=0;
flg=1;
}
flag=~flag;
if(miao==60)
{
miao = 0;
fen++;
if(fen == 60)
{
fen = 0;
shi++;
if(shi == 24)
{
shi = 0;
}
}
}
}
tempdata[0] = segdata[shi / 10];
tempdata[1] = segdata[shi % 10];
tempdata[3] = segdata[fen / 10];
tempdata[4] = segdata[fen % 10];
tempdata[6] = segdata[miao / 10];
tempdata[7] = segdata[miao % 10];
if(flag){
tempdata[2] = 0x40;
tempdata[5] = 0x40;
}else{
tempdata[2] = 0x00;
tempdata[5] = 0x00;
}
}
void main()
{
unsigned int j=0;
timer0_init();
uart_init();
while(1)
{
if(flg){
flg=0;
uart_send_str("now time is:\n");
uart_send_byte((shi/10)+0x30);
uart_send_byte((shi%10)+0x30);
uart_send_byte(':');
uart_send_byte((fen/10)+0x30);
uart_send_byte((fen%10)+0x30);
uart_send_byte(':');
uart_send_byte((miao/10)+0x30);
uart_send_byte((miao%10)+0x30);
uart_send_str("\r\n");
}
if(!strncmp("0x01",temp,4)){
clean();
while(1){
unsigned char i = 0;
for(;i<8;i++){
P2=bitdata[i];
P1 = segdata[0];
delay_us(100);
}
if(!strncmp("0x02",temp,4)){
clean();
break;
}
}
}
if(biao){
biao=0;
if(infodata()){
hour = ((unsigned int)temp[5] - 48) * 10 + ((unsigned int)temp[6] - 48);
min= ((unsigned int)temp[8] - 48)* 10 + ((unsigned int)temp[9] - 48);
sen = ((unsigned int)temp[11] - 48)* 10 + ((unsigned int)temp[12] - 48);
}
if(hour>=0&&hour<=24&&min>=0&&min<60&&sen>=0&&sen<60){
shi=hour;
fen=min;
miao=sen;
}else{
uart_send_str("The Time is error");
uart_send_str("\r\n");
}
clean();
}
display();
}
}
实验效果图
时钟显示
电脑发送指令0x01
设置时钟
返回时间