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

📄 main.c

📁 我学习AVR的代码例子
💻 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 + -