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

📄 handmeteravr.c

📁 AVR单片机应用开发指南及实例,包含许多实例,挺不错
💻 C
字号:
#include "iom32v.h"
#include <macros.h>
#define         uchar   unsigned char
#define         uint    unsigned int

#define         _SLEEP()	asm("sleep")

//****I/O define*************** 
//LCD
#define         lcd_rw        2     //PC2     O  
#define         lcd_en        3     //PC3     O LCD使能
#define         lcd_con       4     //PC4     O
#define         lcd_cs1       5     //PC5     O
#define         lcd_cs2       6     //PC6     O
#define         lcd_el        7     //PC7     O  背光


//uart data
#define         r232_txd       0     //PD0     I 
#define         r232_rxd       1     //PD1     O 
//control   
#define         power_c        7     //PD7     O 电源控制
#define         power_s        2     //PD2     I 电源检测      
#define         key_int        3     //PD3     I 键盘检测      
#define         mode_bit       4     //PD4     I     
#define         se_HW          6     //PD6     O       
//flash
#define         spi_cs         2     //PB2     O  片选
#define         spi_rdy        1     //PB1     I  忙标志 
#define         spi_rst        0     //PB0     O   
//*****************************

//**********************
//变量  常量定义
#define        wr_device_add        0x64       //时钟器件地址写命令
#define        rd_device_add        0x65       //器件地址读命令


#define   START      0x08 
#define   RE_START   0x10 
#define   MT_SLA_ACK   0x18 
#define   MT_DATA_ACK   0x28 
#define   MR_SLA_ACK   0x40 
#define   MR_DATA_ACK   0x50 
#define   MR_DATA_NAK   0x58 



#define Start()         (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) 
#define Stop()          (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) 
#define Wait()           {while(!(TWCR&(1<<TWINT)));} 
#define TestAck()      (TWSR&0xf8) 
#define SetAck()     (TWCR|=(1<<TWEA)) 
#define SetNoAck()    (TWCR&=~(1<<TWEA)) 
#define Twi()          (TWCR=(1<<TWINT)|(1<<TWEN)) 
#define Write8Bit(x)  {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}  

#define   KEY_CHIP_ADDR            0x70        //键盘器件地址
#define   KEY_STATUS_ADDR          0x00        //状态地址
#define   KEY_VALUE_ADDR           0x01        //键值地址
                                               //键值对应
#define   ZERO_KEY                 0x01        //     ;0
#define   ONE_KEY                  0x02        //      ;1
#define   TWO_KEY                  0x03        //      ;2
#define   THREE_KEY                0x04        //      ;3
#define   FOUR_KEY                 0x05        //        ;4
#define   FIVE_KEY                 0x09        //      ;5
#define   SIX_KEY                  0x0A        //     ;6
#define   SEVEN_KEY                0x0B        //     ;7
#define   EIGHT_KEY                0x0C        //     ;8
#define   NINE_KEY                 0x0D        //     ;9
#define   VLCD_KEY                 0x19        //     ;VLCD(el) KEY NUMBER
#define   FUNC_KEY                 0x15        //     ;FUNCTION
#define   SET_KEY                  0x13        //    ;SET
#define   READ_KEY                 0x14        //     ;READ
#define   UP_KEY                   0x11        //     ;SELECT_UP
#define   DOWN_KEY                 0x12        //     ;SELECT_DOWN
#define   ENTER_KEY                0x1A        //     ;ENTER
#define   CANCEL_KEY                0x1B        //     ;CANCEL


#define    F_READ_STATUS_CMD                   0xD7       //STATUS_READ
#define    F_WRITE_BUFFER1_CMD                 0x84       //write buffer1
#define   F_WRITE_BUFFER2_CMD                  0x87       //write buffer2
#define   F_READ_BUFFER1_CMD                   0x54       //READ BUFFER1
#define   F_READ_BUFFER2_CMD                   0x56       //READ BUFFER2
#define   F_WRITE_BUFFER1_TO_Page_CMD          0x83       //write buffer1 to page
#define   F_WRITE_BUFFER2_TO_Page_CMD          0x86       //write buffer2 to page
#define   F_READ_Page_TO_BUFFER1_CMD           0x53       //read main to buffer1
#define   F_READ_Page_TO_BUFFER2_CMD           0x55       //read main to buffer2
#define   F_READ_PAGE_CMD                      0x52       //directly from main to ram
#define   F_BUFFER_NUMBER1                     0x01       //

#define   VLCD_ON                              0x12       //背光开
#define   VLCD_OFF                             0x21       //背光关
uchar   terminal_numh;      //终端号  HEX
uchar   terminal_numl;

uchar   hand_no_h    ;      //便携设备号
uchar   hand_no_l    ;

uchar   crcram_h     ;      //
uchar   crcram_l     ;

uchar   f_page_addrh  ;     //flash页地址缓存0~2048
uchar   f_page_addrl  ;
uchar   f_data_addr   ;     //数据地址0~255
uchar   f_data_num    ;     //数据个数0~255
uchar   cpu_data_ram_addr;  //
uchar   f_page_addrth ;     //内部地址
uchar   f_page_addrtl ;
uchar   f_page_byte_addr;

uchar   terminal_addrh  ;     //终端号  BCD
uchar   terminal_addrl  ;    

uchar   key_status=false;
uchar   key_value;           //键号缓存
uchar   bat_warning_s;       //电池电压

uchar   password_status;     //权限状态
uchar   password[2];         //密码
uchar   password_mode;       //权限区分

uchar   vlcd_status=0x21;         //LCD 背光状态   0x12 表示目前开,0x21表示目前关
 const  uchar   default_time[14]={'2','0','0','6','0','6','0','6','0','6','0','6','0','6'};
 uchar    now_time[12];
 uchar    now_time_hex[6];
 uchar    timer_set;
 uchar    hw_commd_h;       //红外通讯命令
 uchar    hw_commd_l;
 uchar    hw_rx_tx;
 uchar    hw_crc;
 
 uchar    hw_data_buffer[50];   //红外通讯数据缓存,包括打印
 
 uchar    usb_commd_h;      //USB通讯命令
 uchar    usb_commd_l;
 uchar    usb_rx_tx;
 uchar    usb_crc;
 uchar    usb_err;
 uchar    usb_data_buffer[120];   //USB通讯数据缓存
 
 uchar    real_data_save[100];    //需要保存的数据
 
///子程序
/*UART---外部设备 初始化*/	
void uart_out_init(void)
 {
 UCSRB=0xd8; //11011000   接收和发送中断,接收和发送使能
 UBRRL=23  ;//   23   9600   //(fosc/16/(baud+1))%256;
 UBRRH=0x00  ; //  (fosc/16/(baud+1))/256;
 UCSRC=0x86 ; //
 }

/* 延时us 子程序 */
void delay_us(int time)             //us  delay
	 {     
  	  do
	  	{
	  	 
		 time--;
		}	
  	  while (time>1);
	 }	

/*延时ms子程序 ms delay */	 
void delay_ms(unsigned int time)
	 {
	  while(time!=0)
	  	  {
	  	   WDR();			
		   delay_us(500);
		   time--;
		  }
         }


//iic 初始化
void  iic_init(void)
      {
      TWSR=00;
      TWBR=0x16;     //50K
      }
//I/O口方向初始化
void  io_init(void)
      {
    DDRA=0xff;  
    DDRB=0xC5;                   
    DDRC=0xcf;
    DDRD=0xff;
      }


   

//红外
void USART0_Transmit( unsigned char data )
{
/* 等待发送缓冲器为空*/
       PORTC &=~(1<<se_hw);          //选通
       delay_us(100);
                     do
                     {
                     WDR();	
                     }
                   while ( !( UCSRA & (1<<UDRE)) );



/* 将数据放入缓冲器,发送数据*/
UDR = data;
}
//打印
void USART1_Transmit( unsigned char data )
{
/* 等待发送缓冲器为空*/
       
       PORTC |=(1<<se_hw);          //选通
       delay_us(100);
                    do
                     {
                     WDR();	
                     }
while ( !( UCSRA & (1<<UDRE)) );

/* 将数据放入缓冲器,发送数据*/
UDR = data;
}

//关闭看门狗
void WDT_off(void)
{
/* 置位WDCE 和WDE */
WDTCR = (1<<WDCE) | (1<<WDE);
/* 关闭WDT */
WDTCR = 0x00;
}

//SPI  初始化
void  spi_init(void)
{
 SPCR=0x51;   //
 SPSR=0x00;   //   
}
/****************************************** 
               I2C总线写一个字节 
             返回0:写成功 
            返回非0:写失败 
*******************************************/ 
unsigned char i2c_Write(unsigned char Wdata,unsigned int RomAddress)  
{ 
  
     Start();//I2C启动 
     Wait(); 
     if(TestAck()!=START) return 1;//ACK 
     Write8Bit(wr_device_add);//写I2C从器件地址和写方式 
     Wait(); 
     if(TestAck()!=MT_SLA_ACK) return 1;//ACK 
      
     Write8Bit(RomAddress);//写地址 
     Wait(); 
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK 
      
     Write8Bit(Wdata);//写数据
     Wait(); 
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK    
      
     Stop();//I2C停止 
     WDR();
     delay_ms(10);//延时等待
     return 0; 
} 
/****************************************** 
               I2C总线读一个字节 
            如果读失败也返回0 
*******************************************/ 
unsigned char i2c_Read(unsigned int RomAddress)  
{ 
      unsigned char temp; 
  
      Start();//I2C启动 
      Wait(); 
      if (TestAck()!=START) return 0;//ACK       
      Write8Bit(wr_device_add);//写I2C从器件地址和写方式 
      Wait();  
      if (TestAck()!=MT_SLA_ACK) return 0;//ACK 
       
     // P--; 
      Write8Bit(RomAddress);//写地址 
      Wait(); 
      if (TestAck()!=MT_DATA_ACK) return 0; 
       
  
      Start();//I2C重新启动 
      Wait(); 
      if (TestAck()!=RE_START)  return 0; 
      Write8Bit(rd_device_add);//写I2C从器件地址和读方式 
      Wait(); 
      if(TestAck()!=MR_SLA_ACK)  return 0;//ACK 
      Twi();//启动主I2C读方式 
      Wait(); 
      if(TestAck()!=MR_DATA_NAK) return 0;//ACK    
       
      temp=TWDR;//读取I2C接收数据 
       Stop();//I2C停止 
       WDR();
      return temp; 
} 

//外部中断0服务程序,关设备
         #pragma interrupt_handler EXT_INT0_ISR: iv_INT0  
           void EXT_INT0_ISR (void)    //INT0 中断
{
 uchar   temp;
 temp=SREG;
 delay_ms(10);
 portc &=~(1<<lcd_el);            //关闭背光
 portd &=~(1<<power_c);           //关闭电源
 delay_ms(2000);             //等待关机 
 SREG=temp;

}
//外部中断1服务程序,键盘响应
         #pragma interrupt_handler EXT_INT1_ISR: iv_INT1  
           void EXT_INT1_ISR (void)    //INT1 中断
{
 uchar   temp;
 temp=SREG;
 delay_ms(1);
 read_key_value();           //读取键值
 if(key_vlaue==VLCD_KEY)
 {
   if(vlcd_status==VLCD_ON)
    {
    portc &=~(1<<lcd_el);            //关闭背光
    vlcd_status=0x21;
    }
   else
    {
    portc |=(1<<lcd_el);            //打开背光
    vlcd_status=0x12;
    }
  
 }
 else
 {
  key_status=true;           //有效键
 } 
 SREG=temp;

}

//主程序
void  main(void)
 {
    uchar i, j;
    io_init();
    portd |=(1<<power_c);
    uart_out_init();
    twi_init();
    spi_init();
    MCUCR=0x0f;                      //INT0 ,INT1 上升沿
    GICR =0xc0;                      //INT0,INT1  中断使能
    lcd_init();                      //LCD初始化
    
    lcd_clr();                       //清屏幕
    open_display();                  //开机信息
    SREG=0x80;             //启动总中断,等待键盘响应
    //
    switch(!(PIND&(1<<mode_bit))
    {
     case 0:                        //usb模式
                while(1)
                 {
                  usb_sub();
                 }
                break;
                
     default;                       //红外模式
                EEPROM_read(0x02);  //读出时钟状态
                while(timer_set)  //时钟设置
                   {
                   display_set();
                   wait_time_set();
                   }
                
                
                display_pleasekey();   //提示首界面
                
                 while(1)
                {
                 if(key_status==true)   //判断键有效
                 {
                 key_status=false;	
                 hw_sub();             //处理
                 }
                 else
                 {
                 }
                }
                break;
     
     
    }
        
 }

⌨️ 快捷键说明

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