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

📄 uart_to_twi_m8.c

📁 AVR单片机的T_TO_TWI通讯方式
💻 C
字号:
/*****************************************************************
ICC-AVR application builder : 2005-8-19 14:40:53
 Target : M8
 Crystal: 7.3728Mhz
// Crystal: 4.6080Mhz

实验:做usart串行通讯实验
目的:了解及会使用usart串口
CPU:atmega8L
相关的5个寄存器:UCSRA,UCSRB,UCSRC,UDR,UBRR(UBRRH,UBRRL)
	         其中:UBRRH和UCSRC共用一个地址
******************************************************************/
/*配置:CKOPT=0,CKSEL3..0=1111,SUT1..0=11(65ms慢速上升电源)*/
#include <iom8v.h>
#include <macros.h>
#include "usart_m8.h"
#include "twi_master_polling.h"

//#define test

#define LED_ON   1
#define LED_OFF  0

#define IO_OUT_MAIN_LED   3 //PD3 pin1
#define IO_OUT_SLAVE_LED  2 //PD2 pin32

#define  Main_Led_Off()    PORTD |= BIT(IO_OUT_MAIN_LED)
#define  Slave_Led_Off()   PORTD |= BIT(IO_OUT_SLAVE_LED)
#define  Main_Led_On()     PORTD &= ~BIT(IO_OUT_MAIN_LED)
#define  Slave_Led_On()    PORTD &= ~BIT(IO_OUT_SLAVE_LED)

void init_data(void);
void port_init(void);
void init_devices(void);
void timer0_init(void);
void check_watchdog(void);
void process_data_pack(void);
void twi_transmint(void);
void watchdog_init(void);
void check_main_led(void);
void check_slave_led(void);
void ascii_to_hex(void);
void show_data(unsigned char dat);

unsigned char Twi_Hex_Data[3];
unsigned char Twi_ASCI_Data[6];
unsigned char Twi_Write_Flag,Twi_Read_Flag;
unsigned char Twi_ASCI_Data_Flag,Twi_Hex_Data_Flag;
//LED指示灯
unsigned char Slave_Led_Status;
unsigned char Main_Led_Status,Cur_Main_Led_Status,Count_10ms;



void main(void)
{
	init_devices();
	init_data();
    
	USART_Transmit( "read go!" );//用来指示,是不是看门狗复位
	while(1)  //forever
	   {
		  UART_Receive();
		  check_watchdog();//喂狗
	      process_data_pack();//解包
		  //while(1)WDR();
		  twi_transmint();
	      //while(1)WDR();
		  check_main_led();
		}
       
}
//>>>>>>>>>>>>>>>>>>>>>>>>解包
void process_data_pack(void)
{
   unsigned char cnt,dat;
   
   if(Rx_Over_Pack_Flag == true)
    {   
	    //从灯
		Slave_Led_Status = LED_ON;
		check_slave_led();//先让通讯亮一下
		Rx_Over_Pack_Flag = false;
		Slave_Led_Status = LED_OFF;

		if(UART_RX_buff[1] == 0x57)
		{
		   for(cnt =0;cnt<6;cnt++)
		    {
			   dat = UART_RX_buff[cnt+2];//前面两个字节是'x','w'或'R'
			   if((dat >= 0x30)&&(dat <=0x39))
			    {
				  Twi_ASCI_Data[cnt] = dat - 0x30;
				}
			   else if((dat>=0x41)&&(dat<=0x46))
			    {
				  Twi_ASCI_Data[cnt] = dat - 0x37;//如果是字母,那么减去0x37
				}
		    }
			ascii_to_hex();//组合成数据
		   Twi_Write_Flag = true;
		}
		if(UART_RX_buff[1] == 0x52)
		{
		   for(cnt =0;cnt<4;cnt++)
		    {
			   dat = UART_RX_buff[cnt+2];
			   if((dat >= 0x30)&&(dat <=0x39))
			    {
				  Twi_ASCI_Data[cnt] = dat - 0x30;
				}
			   else if((dat>=0x41)&&(dat<=0x46))
			    {
				  Twi_ASCI_Data[cnt] = dat - 0x37;//如果是字母,那么减去0x37
				}
		    }
			ascii_to_hex();
		   Twi_Read_Flag = true;
		}
		Twi_Hex_Data_Flag = true;
		//处理完,先把数据放在UART_TX_buff[]绶冲区,且接收绶冲区清零
		for(cnt=0;cnt<9;cnt++)
		{
		   UART_TX_buff[cnt] = UART_RX_buff[cnt];
		   UART_RX_buff[cnt] = 0;
		}
		WDR();
	}
}
//继续解包,=>两个ASCII码组成一个数
void ascii_to_hex(void)
{
    unsigned char cnt,i;
   
	for(cnt=0,i=0;cnt<6;cnt++,cnt++,i++)
	{
	  Twi_Hex_Data[i] = Twi_ASCI_Data[cnt];//先放ASCII的高位(四位)
	  Twi_Hex_Data[i] <<= 4;
	  Twi_Hex_Data[i] += Twi_ASCI_Data[cnt+1];
	}
}
void hex_to_ascii(unsigned char dat)
{
    unsigned char dat_buff;
  
    dat_buff = dat;
    dat = dat&0x0f;
    if((dat>=0)&&(dat<=9))
    {
       dat += 0x30;
    }
    else
       dat += 0x37;
	UART_TX_buff[7] = dat;
	  
    dat = dat_buff;
	dat >>= 4;
	dat = dat&0x0f;
    if((dat>=0)&&(dat<=9))
    {
      dat += 0x30;
    }
    else
      dat += 0x37;
	UART_TX_buff[6] = dat;
}
//<<<<<<<<<<<<<<<<<<<<<
/***********************************************************************
通用的hex转成ascii
************************************************************************/
unsigned char general_hex_to_ascii(unsigned char dat)
{
    dat = dat & 0x0f;
    if((dat >= 0)&&(dat <= 9))
    {
	  dat = dat + 0x30;
	}
	else
	{
	  dat += 0x37;
	}
	return dat;
}
/************************************************************************
通用的,,用来显示一个变量的值,,送到串口来
*************************************************************************/
void show_data(unsigned char dat)
{
    unsigned char dat_buff;
	
    dat_buff = dat;
	dat >>= 4;
	dat = dat & 0x0f;
	dat = general_hex_to_ascii( dat );
	USART_TransmitByte(dat);
	dat = dat_buff;
	dat = dat & 0x0f;
	dat = general_hex_to_ascii( dat );
	USART_TransmitByte(dat);
}
//>>>>>>>>>>>>>>>>做包
void twi_transmint(void)
 {
    unsigned char dat1,dat2;
	unsigned char dat1_buff;
  
    if(Twi_Hex_Data_Flag == true)
    {
	    
	    Twi_Hex_Data_Flag = false;
		if(Twi_Write_Flag == true)
		{
		    Twi_Write_Flag = false;
	        dat1 = twi_write_byte(Twi_Hex_Data[0],Twi_Hex_Data[1],Twi_Hex_Data[2]);
		
		    #ifdef test
			//显示TWI状态字
			show_data(dat1);
			USART_Transmit("this is write!");
			#endif
		
			if(Write_Succsee_Flag == true)
			{
				Write_Succsee_Flag = false;
				
				USART_Transmit(UART_TX_buff);//写成功
				#ifdef test
				USART_Transmit("write successfully!");
				#endif
			}
			else
			{
				USART_Transmit(Write_Error);//写不成功
				#ifdef test
			    USART_Transmit("write error!");
				#endif
			}
			WDR();
		}
		if(Twi_Read_Flag == true)
        {
			Twi_Read_Flag = false;
			dat2 = twi_read_byte(Twi_Hex_Data[0],Twi_Hex_Data[1]);
			#ifdef test
			show_data(dat2);
			USART_Transmit("this is read!");
			#endif
			
			if(Read_Succsee_Flag  != true)
			{
				USART_Transmit(Read_Error);//读失败
				#ifdef test
				USART_Transmit("read error!");
				#endif
			}
			else
			{
				Read_Succsee_Flag  = false;
				
				hex_to_ascii(dat2);//读成功 且读的数在dat2中				
				USART_Transmit(UART_TX_buff);
				#ifdef test
				USART_Transmit("read successfully!");
				#endif
			}
			WDR();
		}
	}
 }

void init_data(void)
{
   Twi_Write_Flag     = false;
   Twi_Read_Flag      = false;
   Twi_Hex_Data_Flag  = false;      
   Twi_ASCI_Data_Flag = false;
   Slave_Led_Status   = LED_OFF;
   Main_Led_Status    = LED_OFF;
   Cur_Main_Led_Status= LED_OFF;
   Count_10ms         = 0;
   WDR();
}
void port_init(void)
{
 PORTB = 0x3F;
 DDRB  = 0x00;
 PORTC = 0x4F; //m103 output only
 DDRC  = 0x00;
 PORTD = 0xFC;
 DDRD  = 0x00;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 uart0_init();
 twi_init();
 timer0_init();
 watchdog_init();

 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}
void check_watchdog(void)
{
 	WDR();//喂狗
}
void watchdog_init(void)
{
 WDR();//看门狗计数清零
 WDTCR=((1<<WDE)|(1<<WDP2)|(1<<WDP0));//64K分频,0.52S
 //WDIE是看门狗中断使能,WDE看门狗使能 101 512k
}

//TIMER0 initialize - prescale:256
// desired value: 100Hz
// actual value: 100.000Hz (0.0%)
void timer0_init(void)
{
 TCCR0 = 0x00; //stop
 TCNT0 = 0x4C; //set count
 TCCR0 = 0x04; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
    TCNT0 = 0x4C; //reload counter value
    //主灯
    Count_10ms++;
    if((Count_10ms>0)&&(Count_10ms<5))
    {
       Cur_Main_Led_Status = LED_ON;
	}
    if((Count_10ms>5)&&(Count_10ms<10))
    {
      Cur_Main_Led_Status = LED_OFF;
    }
}
void check_main_led(void)
{
   if(Main_Led_Status != Cur_Main_Led_Status)
   {
 	  if(Main_Led_Status == LED_ON) 	   Main_Led_Off();
	  else		   	  		   	   Main_Led_On();
	  Main_Led_Status = Cur_Main_Led_Status;
   }
}
void check_slave_led(void)
{
    if(Slave_Led_Status == LED_ON) 
    {
      Slave_Led_On();
	}
	else		   	  		   	  
    {
      Slave_Led_Off();
    }
}









⌨️ 快捷键说明

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