两片STC89C52RC进行双机通信,连接电路如图,传输波特率=4800。用U1控制U2的工作,U2的P2.0发出PWM波控制发光二极管L1的亮度,PWM的周期是20ms,其占空比按百分比存放在30H,31H,32H三个单元中,为十进制数。分别设计两片STC89C52RC的程序,完成以下功能: 1、当S1按钮按下时,U1把30H=90发送给U2,U2将其保存在40H单元中,并从P2.0输出,控制L1的亮度为90%。 2、当S1按钮按下时,U1把31H=50发送给U2,U2将其保存在41H单元中,并从P2.0输出,控制L1的亮度为50%。 3、当S1按钮按下时,U1把32H=20发送给U2,U2将其保存在42H单元中,并从P2.0输出,控制L1的亮度为20%。 要求完整的程序并加注解。
时间: 2024-03-18 08:42:31 浏览: 170
由于电路图并未提供,故只能给出程序代码。
U1代码:
```c
#include <STC89C5xRC.H>
#define FOSC 11059200UL // 单片机晶振频率
#define BAUD 9600 // 串口波特率
#define TIMER1MS (65536-FOSC/1000) // 定时器初值
sbit S1 = P3^2; // S1按钮连接到P3.2
void UART_Init() {
SCON = 0x50; // 设置串口工作模式,8位数据位,波特率可变
TMOD |= 0x20; // 设置定时器1工作模式,自动重装载
TH1 = TL1 = TIMER1MS/BAUD; // 设置波特率
ET1 = 0; // 关闭定时器1中断
TR1 = 1; // 启动定时器1
}
void UART_SendByte(unsigned char dat) {
SBUF = dat; // 将数据存入串口发送缓存
while(TI == 0); // 等待发送完成
TI = 0;
}
void UART_SendString(unsigned char *s) {
while(*s) {
UART_SendByte(*s++);
}
}
unsigned char UART_ReceiveByte() {
while(RI == 0); // 等待接收完成
RI = 0;
return SBUF; // 返回接收到的数据
}
void main() {
unsigned char pwm = 0x30; // 初始占空比为30%
UART_Init(); // 初始化串口
while(1) {
if(S1 == 0) { // 如果按钮被按下
UART_SendByte(pwm); // 向U2发送占空比
while(S1 == 0); // 等待按钮释放
}
pwm++; // 增加占空比
if(pwm > 0x32) { // 如果占空比已经到达最大值
pwm = 0x30; // 重置占空比
}
TH1 = TL1 = TIMER1MS/BAUD; // 重新设置波特率
}
}
```
U2代码:
```c
#include <STC89C5xRC.H>
#define FOSC 11059200UL // 单片机晶振频率
#define BAUD 9600 // 串口波特率
#define TIMER1MS (65536-FOSC/1000) // 定时器初值
sbit LED = P2^0; // LED连接到P2.0
void UART_Init() {
SCON = 0x50; // 设置串口工作模式,8位数据位,波特率可变
TMOD |= 0x20; // 设置定时器1工作模式,自动重装载
TH1 = TL1 = TIMER1MS/BAUD; // 设置波特率
ET1 = 0; // 关闭定时器1中断
TR1 = 1; // 启动定时器1
}
unsigned char UART_ReceiveByte() {
while(RI == 0); // 等待接收完成
RI = 0;
return SBUF; // 返回接收到的数据
}
void PWM_Init() {
TMOD |= 0x01; // 设置定时器0工作模式,16位自动重装载
TH0 = 0xff; // 设置定时器0初值,PWM周期为20ms
TL0 = 0xf0;
ET0 = 1; // 开启定时器0中断
TR0 = 1; // 启动定时器0
}
void main() {
unsigned char pwm = 0; // 初始占空比为0%
UART_Init(); // 初始化串口
PWM_Init(); // 初始化PWM
while(1) {
pwm = UART_ReceiveByte(); // 接收U1发送的占空比
switch(pwm) {
case 0x30: // 如果是30H
P40 = pwm; // 保存到40H
CCAP0H = CCAP0L = (unsigned char)(65535 - (20*48*9)/10); // 设置PWM占空比为90%
break;
case 0x31: // 如果是31H
P41 = pwm; // 保存到41H
CCAP0H = CCAP0L = (unsigned char)(65535 - (20*48*5)/10); // 设置PWM占空比为50%
break;
case 0x32: // 如果是32H
P42 = pwm; // 保存到42H
CCAP0H = CCAP0L = (unsigned char)(65535 - (20*48*2)/10); // 设置PWM占空比为20%
break;
default:
break;
}
}
}
void Timer0_ISR() interrupt 1 {
LED = !LED; // 翻转LED状态
}
```
阅读全文