📄 main.c
字号:
//编译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 + -