单片机P31接底板JP75的TX1,单片机P30接底板JP75的RX1。 底板JP71的PCR1接底板JP8的RX,底板JP71的PCT1接底板 JP8的TX(串口线接DB1串口母座) 1、串口通信初始化,包括SCON设置,通信波特率发生器设置 (TMOD,TCON,TH1,TL1,SMOD等的设置) 2、中断初始化,包括IE,IP等特殊功能寄存器设置 3、启动定时器TR1 4、根据接收到来自PC串口助手数据,送出并实现8路指示灯的显示 5、读入8位拨码值,若有变化,则把最新拨码值发送到PC机 编码:显示功能考虑使用三位数码管实时显示0~256的串口接收数值
时间: 2023-10-08 12:08:36 浏览: 137
2022年单片机原理与接口技术4.ppt
好的,下面是程序代码:
``` c
#include <reg52.h>
#define FOSC 11059200L
#define BAUD 9600
#define TIMER_1MS (65536 - FOSC / 12 / 1000) // 1ms定时器计数值
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;
sbit LED5 = P2^4;
sbit LED6 = P2^5;
sbit LED7 = P2^6;
sbit LED8 = P2^7;
sbit D1 = P1^0;
sbit D2 = P1^1;
sbit D3 = P1^2;
unsigned char code ledTab[] = {
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, // 0~9
0xbf, 0xff, 0x7f, // -, ., 空格
};
unsigned char idata rxData = 0; // 串口接收数据
unsigned char idata dipVal = 0; // 拨码开关值
unsigned char idata lastDipVal = 0xff; // 上一次拨码开关值
unsigned char idata dispVal = 0; // 数码管显示值
unsigned char idata dispCnt = 0; // 数码管显示计数
void initSerial() {
SCON = 0x50; // 8位数据位,可变波特率
TMOD &= 0x0f;
TMOD |= 0x20; // Timer1工作在模式2,8位自动重装载
TL1 = TH1 = TIMER_1MS / BAUD / 2; // 设置波特率发生器初值
TR1 = 1; // 启动定时器1
ES = 1; // 使能串口中断
EA = 1; // 使能总中断
}
void initInterrupt() {
IT1 = 1; // 选择下降沿触发
EX1 = 1; // 使能外部中断1
P3 |= 0x02; // 使能P3.1上拉电阻
}
void initTimer0() {
TMOD &= 0xf0; // 清零低四位
TMOD |= 0x01; // 16位定时器模式
TH0 = 0; // 定时器初值
TL0 = 0;
ET0 = 1; // 使能定时器0中断
TR0 = 1; // 启动定时器0
}
void updateLED() {
LED1 = !!(rxData & 0x01);
LED2 = !!(rxData & 0x02);
LED3 = !!(rxData & 0x04);
LED4 = !!(rxData & 0x08);
LED5 = !!(rxData & 0x10);
LED6 = !!(rxData & 0x20);
LED7 = !!(rxData & 0x40);
LED8 = !!(rxData & 0x80);
}
void updateDipVal() {
unsigned char val = 0;
if (!D1) val |= 0x01;
if (!D2) val |= 0x02;
if (!D3) val |= 0x04;
dipVal = val;
}
void display() {
unsigned char i, j, k;
unsigned int tmp = dispVal;
for (i = 0; i < 3; i++) {
j = tmp % 10;
tmp /= 10;
k = ledTab[j];
if (i == 0 && tmp == 0) k = 0xff; // 高位为0不显示
P0 = k;
P1 = ~(1 << i);
for (j = 0; j < 100; j++); // 稍作延时
}
}
void main() {
initSerial();
initInterrupt();
initTimer0();
while (1) {
if (dipVal != lastDipVal) {
SBUF = dipVal;
while (!TI); // 等待发送完成
TI = 0; // 清除发送完成标志
lastDipVal = dipVal;
}
if (dispCnt == 0) {
dispVal = rxData;
display();
}
}
}
void serialISR() interrupt 4 using 1 {
if (RI) {
rxData = SBUF;
RI = 0; // 清除接收中断标志
}
if (TI) {
TI = 0; // 清除发送完成标志
}
}
void extISR() interrupt 2 {
updateDipVal();
}
void timer0ISR() interrupt 1 {
TH0 = (65536 - FOSC / 12 / 1000) / 256;
TL0 = (65536 - FOSC / 12 / 1000) % 256;
dispCnt = (dispCnt + 1) % 50; // 每50ms刷新一次数码管
updateLED();
}
```
注:本程序使用的是STC89C52RC单片机,如果使用其他型号的单片机需要修改代码中的寄存器地址。
阅读全文