⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m16-11__.c

📁 AVR单片机之间多机通信(通信方式采用的中断进行)
💻 C
字号:
//从机11
#include <mega16.h>
	#ifndef __SLEEP_DEFINED__
	#define __SLEEP_DEFINED__
	.EQU __se_bit=0x40
	.EQU __sm_mask=0xB0
	.EQU __sm_powerdown=0x20
	.EQU __sm_powersave=0x30
	.EQU __sm_standby=0xA0
	.EQU __sm_ext_standby=0xB0
	.EQU __sm_adc_noise_red=0x10
	.SET power_ctrl_reg=mcucr
	#endif
#include <usart.h>
#include <crc8.h>

#define  address 11                                        //请在这里设定本机地址
#define  amount  10                                        //设定通讯数据量
#define  max485_out       PORTD.2=1                        //RS485输出使能
#define  max485_in        PORTD.2=0                        //RS485输入使能
#define  max485_RW_ok     DDRD.2=1                         //控制MAX485
#define  data_bit8_1      UCSRB|=1                         //数据的第8位
#define  data_bit8_0      UCSRB&=254
#define  data_in_error    UCSRA&28                         //检测接收到的数据是否有错误
#define  address_on       UCSRA|=0x01                      //打开地址筛选
#define  address_off      UCSRA&=254                       //关闭地址筛选
#define  address_bit8     UCSRB&2                          //检测数据的第8位

unsigned char  send[amount];                               //发件箱
unsigned char inbox[amount];                               //收件箱
unsigned char m=0,n=0;                                     //记忆中断次数

//**************************************************************************************

interrupt[12] Rxd_isr(void)                                //接收中断
{
  if( data_in_error ){ n=UDR; n=0; address_on; } else      //接收出错就重新打开地址帧筛选功能
  {
    if( address_bit8  ) n=0;                               //检测到地址信息时计数清零
    inbox[n]=UDR;  n++;                                    //把接收到的数据保存到收件箱
    if( inbox[0]==address ) address_off; else address_on;  //地址筛选
    if( n==amount )                                        //如果接收到完整的数据包
    {
      n=0;
      if( inbox[amount-1]==crc8(inbox,amount-1) )          //如果crc8校验正确就...
      {
        send[0]=1;                                         //发件箱地址指向主机
        //send[1]=?                                        //请更新发件箱的数据
        //send[n]=?
        send[amount-1]=crc8(send,amount-1);                //产生发件箱的crc8校验码
        max485_out;                                        //使能MAX485准备发送
        m=0;                                               //发送计数清零
        data_bit8_1;                                       //第0个是地址数据
        UDR=send[m];                                       //发送第0个数据以便产生发送结束中断

        OCR1A=inbox[3];                                    //收件箱测试(控制T/C1的PWM驱动LED)
      }
    }
  }
}

//**************************************************************************************

interrupt[14] Txd_Txcie_isr(void)                          //发送结束中断
{
  m++;
  data_bit8_0;                                             //数据帧
  if(m<amount) UDR=send[m]; else max485_in;
}

//**************************************************************************************

void main(void)
{
  usart_init();
  max485_in;
  max485_RW_ok;
  TCCR1A   =0B10000001;                                    //OCR1A/PD5/8位快速PWM
  TCCR1B   =0B00001001;                                    //时钟1分频
  DDRD    |=0b00100000;                                    //输出使能
  OCR1A    =255;                                           //初始化PWM输出100%占空比
  #asm("sei")

  while (1)
  {

  };
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -