📄 main.c
字号:
//编译gccavr
//m16
#include <avr/io.h>
//#include <avr/signal.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
//#include <avr/twi.h>
//#include <compat/twi.h>
//#include <stdio.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 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 unsigned char S[11] PROGMEM={0xaf,0x06,0x6d,0x4f,0xc6,0xcb,0xeb,0x0e,0xef,0xcf,0x00};
volatile int month=1;//1~12
volatile int date=1;//1~31
volatile int hours;//0~23
volatile int minutes;//0~59
volatile BYTE senconds;//0~59
volatile BYTE a,b,c;
void port_init(void)//口方向设置
{
DDRA = 0x00;
PORTA = 0x00;
DDRB = 0xff;
DDRC = 0XFC;
DDRD = 0xF0;
}
void delay_us(int time)//微秒级延时程序
{
do
{
time--;
}
while (time>1);
}
void delay_ms(unsigned int time)//毫秒级延时程序
{
while(time!=0)
{
delay_us(1000);
time--;
}
}
/**/
void Delay(void)
{
//volatile unsigned char i;
unsigned char ii;
for(ii=0;ii<10;ii++); //用于调整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();
//delay_us(10);
PORTB |=(1<<SCK); /*置时钟线为高通知被控器开始接收数位*/
Delay();
//delay_us(10);
PORTB &=(~(1<<SCK)); /*钳住总线准备下一个数据位*/
dat=dat<<1; /*发送数据左移一位*/
}
sei();
}
void Start_spi(void)
{
PORTB |=(1<<SS);
PORTB |=(1<<SCK);
PORTB |=(1<<MOSI);
Delay();
//delay_us(10);
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)
{
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
}
//初始化TWI功能
/*
void twi_Init(void)
{
TWBR=73;
}*/
void I2C_init(void)
{
TWBR=2;
TWSR=00;
}
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);//写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)
{
month=(i2c_Read(5) & 0x1f);
date=(i2c_Read(4) & 0x3f);
hours=(i2c_Read(2) & 0x3f);
minutes=(i2c_Read(1) & 0x7f);
senconds=(i2c_Read(0) & 0x7f);
}
void time_init(void)
{
i2c_Write(0,1);
i2c_Write(0,2);
i2c_Write(0,3);
i2c_Write(0,4);
i2c_Write(0,5);
}
void disp(void)
{
a=HIBYTE(hours);
b=HIBYTE(minutes);
c=HIBYTE(senconds);
if(a==0) a=10;
if(b==0) b=10;
if(c==0) c=10;
SENDCOMB(0x1c); //Write address
SendByte(pgm_read_byte(S+a)); //write data
SendByte(pgm_read_byte(S+LOBYTE(hours))); //write data
SendByte(pgm_read_byte(S+b)); //write data
SendByte(pgm_read_byte(S+LOBYTE(minutes))); //write data
SendByte(pgm_read_byte(S+c)); //write data
SendByte(pgm_read_byte(S+LOBYTE(senconds))); //write data
/*
a=HIBYTE(month);
b=HIBYTE(date);
SENDCOMB(0x2c); //Write address
SendByte(pgm_read_byte(S+a)); //write data
SendByte(pgm_read_byte(S+LOBYTE(month))); //write data
SendByte(pgm_read_byte(S+HIBYTE(date))); //write data
SendByte((pgm_read_byte(S+LOBYTE(date))); //write data
*/
}
//#pragma interrupt_handler timer1_ovf:9
//void timer1_ovf(void) //位闪动即修改
SIGNAL(SIG_OVERFLOW1)
{
TCNT1H=0xc2;
TCNT1L=0xf7;
TCCR1B=0x04;
Gettime();
disp();
}
void start_t1(void)
{
TCNT1H=0xc2;
TCNT1L=0xf7; //设初值
TCCR1B=0X05; //启动定时器1,采用1024分频
TIMSK|=(1<<TOIE1);
sei();
}
int main(void)
{
port_init();
disp_init();
I2C_init();
time_init();
delay_ms(10);
start_t1();
while(1)
{
delay_ms(100);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -