以下回复参考:皆我百晓生、券券喵儿等免费微信小程序作答:
要实现一个AT89C51单片机的串行通信模块,且不需要使用SBUF寄存器,可以采用以下方法:
首先,定义一些常量用于初始化和配置串行接口。
#define RX_PIN P3_0 // 设置接收端口为P3.0
#define TX_PIN P3_1 // 设置发送端口为P3.1
// 初始化串行通信时钟频率
const uint32_t clock_freq = 16000000; // 16MHz
接下来,创建一个函数用于启动定时器T1并初始化它。
void initTimerT1(uint32_t freq) {
TCCR1A = (TCCR1A & ~((1 << WGM12) | (1 << CS12))) | ((freq / clock_freq) << CS12); // 设置定时器工作模式和预分频系数
TCCR1B = (TCCR1B & ~((1 << WGM12) | (1 << CS12))) | ((freq / clock_freq) << CS12); // 设置定时器工作模式和预分频系数
TIMSK1 |= (1 << OCIE1A); // 启动定时器溢出触发
}
然后,编写一个函数来控制串行发送数据。
void sendData(char *data, size_t len) {
for(size_t i = 0; i < len; ++i) {
TMOD1 &= ~(1 << MISO); // 清除MISO引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输出高电平有效
TCNT1 = (uint16_t)(len - i - 1); // 设置计数器值
OCR1A = (uint8_t)(len - i); // 设置溢出触发器
delayMicroseconds(1); // 延迟1微秒
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输出允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输出高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输出允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输出高电平有效
delayMicroseconds(1); // 延迟1微秒
TMOD1 |= (1 << MISO); // 向MISO引脚输出高电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输出允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输出高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输出允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输出高电平有效
delayMicroseconds(1); // 延迟1微秒
}
}
现在,我们需要一个函数来控制串行接收数据。
void receiveData(void) {
TMOD1 &= ~(1 << MISO); // 清除MISO引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
while(TI1IF & TI1IFG) { // 等待串行收到的数据到达
if(TI1IF & TI1IFG) {
TMOD1 &= ~(1 << MISO); // 清除MISO引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MCK); // 设置MCK引脚作为串行输入高电平有效
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许标志位
TMOD1 |= (1 << MISO); // 向MISO引脚输出低电平
TMOD1 &= ~(1 << MCK); // 清除MCK引脚输入允许