Atmega16A通过串口软件发送字符串控制LED灯亮和灯灭

 

文章目录

  • 前言
  • 一、串口配置
  • 二、串口中断
  • 三、接收判断
  • 四、贴心附上主函数,和CodeVisionAVR软件资料和progisp程序下载软件(百度云)

 


前言

单片机课程实践题目:

*计算机控制设备灯(LED1~LED8,低电平亮,高电平灭),串口

        Cx:第x灯亮                Fx:第x灯灭

此处省略:

 昨天avr单片机实验课划了半天水,实在不晓得怎么做,又不晓得如何Dbug好头疼。为了下节课交差,凭借我STM32一点薄弱的技术,花一天终于搞定,晚上顺便发篇文章。ba63645fa4a940afad2c83db67593f3a.gif

        特别鸣谢东东亲友团的鼎力相助,么么哒

 


 

一、串口配置

  1. 我配置的波特率:9600    b/s
  2. 系统时钟为16M
  3. 公式计算:BAUD_SETTING=16M / (16 * (9600  - 1)) = 16*10^6/ (16*9599) = 104.178;
  4. UBRRH=(unsigned char)BAUD_SETTING>>8;
  5. 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;
       }
   }
}

 

三、接收判断

控制灯的话:

  1. PORTA&=~(0x01<<0);让指定的灯为低电平,不改变其他灯;
  2. PORTA&=~(0x01<<0);PORTA|=0x01<<0;我先把对应位清零,再置一,不影响其它位;
  3. 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的分享

905f1c399e254a88ad2d1486cc87f7f7.png

 

 

 

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值