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

📄 main.c

📁 我学习AVR的代码例子
💻 C
📖 第 1 页 / 共 2 页
字号:
//编译gccavr
//m16
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>
//#include "avr/wdt.h"
#include "avr/interrupt.h"
#include <avr/sleep.h>

#define LOBYTE(a) ((BYTE)(a&0X0f))
#define HIBYTE(a) ((BYTE)((a)>>4))
#define LOBCD(b) (b%10)
#define HIBCD(b) (b/10)
#define BCD(c) (((c/10)<<4)|LOBYTE(c%10))
#define DEC(d) (HIBYTE(d)*10+LOBYTE(d))

#define _asm asm
#define WDR() 	asm("wdr")
#define SEI()	asm("sei")
#define CLI()	asm("cli")
//#define NOP()	asm("nop")
#define SLEEP() asm("SLEEP")
#define down() (MCUCR =0x60)
#define int1() (GICR =0x80)
#define int1_off() (GICR =0x00)

//TWI状态定义
//MT 主方式传输  MR 主方式接收
#define START 0x08
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_SLA_NOACK 0x20
#define MT_DATA_ACK  0x28
#define MT_DATA_NOACK 0x30
#define MR_SLA_ACK  0x40
#define MR_SLA_NOACK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NOACK 0x58

#define rd_device_add 0xd1
#define wr_device_add 0xd0
//常用TWI操作(主模式写和主模式读)
#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 SS PB4
#define MOSI PB5
#define SCK PB7

typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
//prog_uchar
const BYTE S[]  PROGMEM={0xaf,0x06,0x6d,0x4f,0xc6,0xcb,0xeb,0x0e,0xef,0xcf,0x00};

int month=1;//1~12
int date=1;//1~31
int hours;//0~23
int minutes;//0~59
BYTE senconds;//0~59

BYTE N=0;//0~3
BYTE M[2];//0~4
WORD T;                         //灯丝状态判断等待次数
BYTE Old_hours=0;               //预存时间
BYTE Old_minutes=0;
BYTE Old_senconds=0;//0~59
BYTE Sign1=0;                   //计时标志
BYTE ADC_ov=0;
BYTE Tov2=0;
WORD Tov0=0;
BYTE Tov1=0;                    //定时器溢出
BYTE Fuse1=1;                   //灯丝1状态
BYTE Fuse2=1;                   //灯丝2状态
WORD tmp_old[2]={0,0};
WORD tmp_rel[2];
BYTE sign2;                     //极性
BYTE Close[4];                  //门状态
BYTE ADC_mux;
WORD ADC_rel;
BYTE a,b,c;
void port_init(void)//口方向设置
 {  
   DDRA  = 0x00;
   PORTA = 0x00;
   DDRB  = 0xff;
   DDRC = 0XFC;
   DDRD  = 0xF0;
 }
void T_init(void)
 {
   TCCR2=0x00;        //停止定时器2
   TCCR1B=0x00;       //停止定时器1
   TCCR0=0x00;        //停止定时器0
   TCNT2=0X64;        //定时~20ms
   TCNT1H=0xc2;
   TCNT1L=0xf7;       //定时0.5s
   TCNT0=6;           //定时32ms
   TCCR2=0x05;        //1024分频
   TCCR1B=0x04;       //256分频
   TCCR0=0x05;        //1024分频
 }
void Delay(void)
 {
   unsigned char i;
   for(i=0;i<10;i++); /*用于调整CLK 脉冲宽度*/
 }
void SendBit(unsigned char dat,unsigned char bitcnt)
 {
   unsigned char i;
   cli();
   for(i=0;i<bitcnt;i++)
     {
       if(( dat & 0X80 ) == 0)
       PORTB &=(~(1<<MOSI));
       else
       PORTB |=(1<<MOSI); /*发送数据由高位到低位传送*/
       Delay();
       PORTB |=(1<<SCK); /*置时钟线为高通知被控器开始接收数位*/
       Delay();
       PORTB &=(~(1<<SCK)); /*钳住总线准备下一个数据位*/
       dat=dat<<1; /*发送数据左移一位*/
     }
   sei();
 }

void Start_spi(void)
 {
   PORTB |=(1<<SS);
   PORTB |=(1<<SCK);
   PORTB |=(1<<MOSI);
   Delay();
   PORTB &=(~(1<<SS));PORTB &=(~(1<<SS));
   PORTB &=(~(1<<SCK));PORTB &=(~(1<<SCK));
 }

void SendByte(unsigned char dat)
 {
   SendBit(dat,8); /*发送字节*/
 }

void SENDCOMA(unsigned char com)
 {
   Start_spi();
   SendBit(0X80,4); //*发送设置命令ID=100 0*
   SendByte(com); //*发送命令字*
 }

void SENDCOMB(unsigned char adr)
 {
   Start_spi();
   SendBit(0XA0,3); /*发送写显示RAM 命令ID=101 */
   SendBit(adr,6); /*指定写入地址*/
 } 
void disp_init(void)
 {
   volatile unsigned char i;
   SENDCOMA(0X0a); /*禁止WDT溢出标志输出*/
   SENDCOMA(0X52); //设置偏压,背极数 定义1/3 偏压4背极
   SENDCOMA(0X30); //*使用内部256KRC 振荡器*
   SENDCOMA(0X02); //*启动振荡器*    
   SENDCOMA(0X06); //LCDON
   SENDCOMA(0X08);//timer dis
   SENDCOMB(0x00); //*把数据指针指回0 接着写入数据*   
   for(i=0;i<15;i++) /*写入16 字节数据*/
     {
       SendByte(0x0); /*写入数据*/
     }
 }
void disp_off(void)
  {
    SENDCOMA(0X04);//lcdoff
    SENDCOMA(0X00);//sys dis
    //SENDCOMA(0X0c);//timer en
  }
void adc_init(void)             //ADC初始化
 {
   ADCSRA=0X00;
   ADMUX=(1<<REFS0);       //选择外部AVCC为基准
   ACSR=(1<<ACD);          //关闭模拟比较器
   ADCSRA=(1<<ADEN) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS0);//32分频
 }
void WDT_init(void)
 {
   WDR();
   WDTCR=0x0e;
 }/**/
void WDT_off(void)
 {
   WDTCR = (1<<WDTOE) | (1<<WDE);
   WDTCR = 0x00;
 }
void I2C_init(void)
 {
   TWBR=2;
   TWSR=00;
 }
void delay_us(int time)//微秒级延时程序
 {     
   do
	 {
	   time--;
	 }	
   while (time>1);
 }	   
void delay_ms(unsigned int time)//毫秒级延时程序
 {
   while(time!=0)
	 {		
	   delay_us(1000);
	   time--;
	 }
 }
unsigned char i2c_Write(unsigned char Wdata,unsigned char 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);//写24C02的ROM地址
   Wait();
   if(TestAck()!=MT_DATA_ACK) return 1;//ACK
   Write8Bit(Wdata);//写数据到24C02的ROM
   Wait();
   if(TestAck()!=MT_DATA_ACK) return 1;//ACK	
   Stop();//I2C停止
   delay_ms(10);//延时等EEPROM写完
   return 0;
 }
unsigned char i2c_Read(unsigned char 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
   Write8Bit(RomAddress);//写24C02的ROM地址
   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_NOACK) return 0;//ACK	
   temp=TWDR;//读取I2C接收数据
   Stop();//I2C停止
   return temp;
 }
void Gettime(void)
 {
   if(N==1)
     {
       month=(i2c_Read(5) & 0x1f);
       date=(i2c_Read(4) & 0x3f);
     }
   else
     {
       hours=(i2c_Read(2) & 0x3f);
       minutes=(i2c_Read(1) & 0x7f);
	   senconds=(i2c_Read(0) & 0x7f);
     }
 }
void time_init(void)
 {
   i2c_Write(0,1);
 }
void disp(void)
 {
   SENDCOMB(0x04);                            //write address
   SendByte(Close[0]<<7 | Close[1]<<1 | Close[2]<<5 | Close[3]<<2);
   if(N==0)
     {
	   a=HIBYTE(hours);
	   b=HIBYTE(minutes);
	   if(a==0) a=10;
	   if(b==0) b=10;
	   if(M[0]==1)
	     {
		   SENDCOMB(0x2c);                        //Write address
           SendByte(pgm_read_byte(S+a)|(Fuse1<<4));            //write data
		   SendByte(pgm_read_byte(S+LOBYTE(hours))|(Fuse2<<4));            //write data	       
		   SendByte((pgm_read_byte(S+HIBYTE(minutes))&Tov1)|(1<<4));  //write data
	       SendByte(pgm_read_byte(S+LOBYTE(minutes))&Tov1);     //write data
		   return;
		 }  
	   if(M[0]==2)
	     {
		   SENDCOMB(0x2c);          //Write address
           SendByte((pgm_read_byte(S+a)&Tov1)|(Fuse1<<4));       //write data
	       SendByte((pgm_read_byte(S+LOBYTE(hours))&Tov1)|(Fuse2<<4));       //write data
		   SendByte(pgm_read_byte(S+HIBYTE(minutes))|(1<<4));   //write data
	       SendByte(pgm_read_byte(S+LOBYTE(minutes)));          //write data
		   return;
		 } 
		if(Tov1==0xff) Tov1=1; 
	    SENDCOMB(0x2c);//秒针闪动
        SendByte(pgm_read_byte(S+a)|(Fuse1<<4));            //write data
	    SendByte(pgm_read_byte(S+LOBYTE(hours))|(Fuse2<<4));            //write data
		SendByte(pgm_read_byte(S+HIBYTE(minutes))|(Tov1<<4));//write data   
		SendByte(pgm_read_byte(S+LOBYTE(minutes)));          //write data
		if(Tov1==1) Tov1=0xff;
		return;                                
	 }
   if(N==1)
     {
	   a=HIBYTE(month);
	   b=HIBYTE(date);
	   if(a==0) a=10;
	   if(b==0) b=10;
	   if(M[0]==1)
	     {
		   SENDCOMB(0x2c);       //Write address
           SendByte(pgm_read_byte(S+a)|(Fuse1<<4));         //write data
	       SendByte(pgm_read_byte(S+LOBYTE(month))|(Fuse2<<4));         //write data
		   SendByte(pgm_read_byte(S+HIBYTE(date))&Tov1);     //write data
	       SendByte((pgm_read_byte(S+LOBYTE(date))&Tov1)|(1<<4));     //write data
		   return;
		 }  
	   if(M[0]==2)
	     {
		   SENDCOMB(0x2c);       //Write address
           SendByte((pgm_read_byte(S+a)&Tov1)|(Fuse1<<4));    //write data
	       SendByte((pgm_read_byte(S+LOBYTE(month))&Tov1)|(Fuse2<<4));    //write data
		   SendByte(pgm_read_byte(S+HIBYTE(date)));          //write data
	       SendByte(pgm_read_byte(S+LOBYTE(date))|(1<<4));          //write data
		   return;
		 }  
	   SENDCOMB(0x2c);                     //Write address
       SendByte(pgm_read_byte(S+a)|(Fuse1<<4));         //write data
	   SendByte(pgm_read_byte(S+LOBYTE(month))|(Fuse2<<4));         //write data
	   SendByte(pgm_read_byte(S+HIBYTE(date)));          //write data
	   SendByte(pgm_read_byte(S+LOBYTE(date))|(1<<4));          //write data
	   return;
	 }
   if(N==2)
     { 
	   if(M[1]==1)
	     {
		   if(Sign1==0)
		     {
	            Old_hours=DEC(hours);
	            Old_minutes=DEC(minutes);
				Old_senconds=DEC(senconds);		  
			    Sign1=1;
		     }
		   a=DEC(hours);
		   b=DEC(minutes);
		   c=DEC(senconds);
		   if(c<Old_senconds) {c+=60;b--;}
		   c=c-Old_senconds;
		   if(b<Old_minutes) {b+=60;a--;}
		   b=b-Old_minutes;
		   if(a<Old_hours) a+=24;

⌨️ 快捷键说明

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