前言
单片机课程实践题目:
*计算机控制设备灯(LED1~LED8,低电平亮,高电平灭),串口
Cx:第x灯亮 Fx:第x灯灭
此处省略:
昨天avr单片机实验课划了半天水,实在不晓得怎么做,又不晓得如何Dbug好头疼。为了下节课交差,凭借我STM32一点薄弱的技术,花一天终于搞定,晚上顺便发篇文章。
特别鸣谢东东亲友团的鼎力相助,么么哒
一、串口配置
- 我配置的波特率:9600 b/s
- 系统时钟为16M
- 公式计算:BAUD_SETTING=16M / (16 * (9600 - 1)) = 16*10^6/ (16*9599) = 104.178;
- UBRRH=(unsigned char)BAUD_SETTING>>8;
- UBRRL=(unsigned char)BAUD_SETTING;
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(1<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=104;
二、串口中断
代码如下:
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
char rx_buffer[2];
char Rx_Ok=0;
unsigned char rx_wr_index=0,rx_rd_index0;
unsigned char rx_counter=0;
void Rx_Proc(void);
void Rx_Control_led(void);
int flag=0;
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;//读取数据寄存器内容
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) // 数据检测一切正常,进行下一步
{
rx_buffer[rx_wr_index++]=data;//存储数据到数组
if(rx_wr_index>1)
{
flag=1;
}
}
}
三、接收判断
控制灯的话:
- PORTA&=~(0x01<<0);让指定的灯为低电平,不改变其他灯;
- PORTA&=~(0x01<<0);PORTA|=0x01<<0;我先把对应位清零,再置一,不影响其它位;
switch()字符判断大家一看都明白,都是聪明人 (偷懒如我)。
代码如下:
void Rx_Control_led(void)
{
printf("RX OK: %s\r\n",rx_buffer);
switch(rx_buffer[0]){
case 'C':switch(rx_buffer[1]){
case '1':PORTA&=~(0x01<<0);printf("C1\r\n");break;
case '2':PORTA&=~(0x01<<1);printf("C2\r\n");break;
case '3':PORTA&=~(0x01<<2);printf("C3\r\n");break;
case '4':PORTA&=~(0x01<<3);printf("C4\r\n");break;
case '5':PORTA&=~(0x01<<4);printf("C5\r\n");break;
case '6':PORTA&=~(0x01<<5);printf("C6\r\n");break;
case '7':PORTA&=~(0x01<<6);printf("C7\r\n");break;
case '8':PORTA&=~(0x01<<7);printf("C8\r\n");break;
}break;
case 'F':switch(rx_buffer[1]){
case '1':PORTA&=~(0x01<<0);PORTA|=0x01<<0;printf("F1\r\n");break;
case '2':PORTA&=~(0x01<<1);PORTA|=0x01<<1;printf("F2\r\n");break;
case '3':PORTA&=~(0x01<<2);PORTA|=0x01<<2;printf("F3\r\n");break;
case '4':PORTA&=~(0x01<<3);PORTA|=0x01<<3;printf("F4\r\n");break;
case '5':PORTA&=~(0x01<<4);PORTA|=0x01<<4;printf("F5\r\n");break;
case '6':PORTA&=~(0x01<<5);PORTA|=0x01<<5;printf("F6\r\n");break;
case '7':PORTA&=~(0x01<<6);PORTA|=0x01<<6;printf("F7\r\n");break;
case '8':PORTA&=~(0x01<<7);PORTA|=0x01<<7;printf("F8\r\n");break;
}break;
default:break;
}
}
四、代码主函数汇总&百度云资料:
前面都是废话,瞎BB一通,复制粘贴不香吗?文章末尾有链接
#include <mega16a.h>
#include <stdio.h>
#include "string.h"
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
char rx_buffer[2];
char Rx_Ok=0;
unsigned char rx_wr_index=0,rx_rd_index0;
unsigned char rx_counter=0;
void Rx_Proc(void);
void Rx_Control_led(void);
int flag=0;
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;//读取数据寄存器内容
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) // 数据检测一切正常,进行下一步
{
rx_buffer[rx_wr_index++]=data;//存储数据到数组
if(rx_wr_index>1)
{
flag=1;
}
}
}
void main(void)
{
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(1<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=104;
#asm("sei")
DDRA = 0xff; //输出模式
PORTA = 0xff; //初始化高电平
while (1)
{
Rx_Proc();
}
}
void Rx_Proc(void)
{
if (flag == 1)
{
Rx_Control_led();
rx_wr_index=0;
flag = 0;
}
}
void Rx_Control_led(void)
{
printf("RX OK: %s\r\n",rx_buffer);
switch(rx_buffer[0]){
case 'C':switch(rx_buffer[1]){
case '1':PORTA&=~(0x01<<0);printf("C1\r\n");break;
case '2':PORTA&=~(0x01<<1);printf("C2\r\n");break;
case '3':PORTA&=~(0x01<<2);printf("C3\r\n");break;
case '4':PORTA&=~(0x01<<3);printf("C4\r\n");break;
case '5':PORTA&=~(0x01<<4);printf("C5\r\n");break;
case '6':PORTA&=~(0x01<<5);printf("C6\r\n");break;
case '7':PORTA&=~(0x01<<6);printf("C7\r\n");break;
case '8':PORTA&=~(0x01<<7);printf("C8\r\n");break;
}break;
case 'F':switch(rx_buffer[1]){
case '1':PORTA&=~(0x01<<0);PORTA|=0x01<<0;printf("F1\r\n");break;
case '2':PORTA&=~(0x01<<1);PORTA|=0x01<<1;printf("F2\r\n");break;
case '3':PORTA&=~(0x01<<2);PORTA|=0x01<<2;printf("F3\r\n");break;
case '4':PORTA&=~(0x01<<3);PORTA|=0x01<<3;printf("F4\r\n");break;
case '5':PORTA&=~(0x01<<4);PORTA|=0x01<<4;printf("F5\r\n");break;
case '6':PORTA&=~(0x01<<5);PORTA|=0x01<<5;printf("F6\r\n");break;
case '7':PORTA&=~(0x01<<6);PORTA|=0x01<<6;printf("F7\r\n");break;
case '8':PORTA&=~(0x01<<7);PORTA|=0x01<<7;printf("F8\r\n");break;
}break;
default:break;
}
}
下载链接:
链接:https://pan.baidu.com/s/12_ppr902X2CI_aIB-FNHCA?pwd=1234
提取码:1234
--来自百度网盘超级会员V1的分享