📄 function.c
字号:
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <util/twi.h>
#include "function.h"
//******************************************************************************
//*******************************delay*****************************************/
//******************************************************************************
void delay_us(unsigned int time)
{//短延时time(us)//
unsigned int i;
for(i=0;i<time;i++)
_delay_us(1);
}
void delay_ms(unsigned int time)
{//长延时time(ms)//
unsigned int i;
for(i=0;i<time;i++)
_delay_ms(1);
}
//******************************************************************************
//*******************************USART FUNCFION********************************/
//******************************************************************************
void Usart_Init(unsigned char com_num,unsigned long baud_rate,unsigned char data_bit,unsigned char stop_bit,unsigned char check_bit)
{//usart串口初始化//端口,波特率,数据位,停止位,校验位
unsigned long baud[8]={4800,9600,14400,19200,28800,38400,57600,115200};
unsigned char baud_set[8]={207,103,68,51,34,25,16,8};
unsigned char i;
for(i=0;i<8;i++)
{
if(baud_rate==baud[i]) break;
}
switch(com_num)
{
case 0:
UCSR0B = 0X00;//USART工作前先停止USART工作
UCSR0A = 0X00;//传输倍率1倍
//配置串口通信///////////////////////////////////////////
bitset(UCSR0C,7);
bitclr(UCSR0C,UMSEL0);//异步传输
switch(check_bit)
{
case 0:
bitclr(UCSR0C,UPM00);//
bitclr(UCSR0C,UPM01);//无校验
break;
case 1:
bitset(UCSR0C,UPM00);
bitset(UCSR0C,UPM01);//奇校验
break;
case 2:
bitclr(UCSR0C,UPM00);
bitset(UCSR0C,UPM01);//偶检验
break;
}
switch(stop_bit)
{
case 1:
bitclr(UCSR0C,USBS0);//1位停止位
break;
case 2:
bitset(UCSR0C,USBS0);//2位停止位
break;
}
switch(data_bit)
{
case 5:
bitclr(UCSR0C,UCSZ00);
bitclr(UCSR0C,UCSZ01);//5位数据位
break;
case 6:
bitset(UCSR0C,UCSZ00);
bitclr(UCSR0C,UCSZ01);//6位数据位
break;
case 7:
bitclr(UCSR0C,UCSZ00);
bitset(UCSR0C,UCSZ01);//7位数据位
break;
case 8:
bitset(UCSR0C,UCSZ00);
bitset(UCSR0C,UCSZ01);//8位数据位
break;
}
bitclr(UCSR0C,UCPOL0); //异步通信时将此位置为0
//配置串口通信///////////////////////////////////////////
// 设置帧格式: 异步8个数据位1个停止奇校验
//UCSR0C = 0x36;//B00110110
// 设置波特率
UBRR0H = 0X00;
UBRR0L = baud_set[i];
// 接收器与发送器使能
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
break;
case 1:
UCSR1B = 0X00;//USART工作前先停止USART工作
UCSR1A = 0X00;//传输倍率1倍
//配置串口通信///////////////////////////////////////////
bitset(UCSR1C,7);
bitclr(UCSR1C,UMSEL1);//异步传输
switch(check_bit)
{
case 0:
bitclr(UCSR1C,UPM10);//
bitclr(UCSR1C,UPM11);//无校验
break;
case 1:
bitset(UCSR1C,UPM10);
bitset(UCSR1C,UPM11);//奇校验
break;
case 2:
bitclr(UCSR1C,UPM10);
bitset(UCSR1C,UPM11);//偶检验
break;
}
switch(stop_bit)
{
case 1:
bitclr(UCSR1C,USBS1);//1位停止位
break;
case 2:
bitset(UCSR1C,USBS1);//2位停止位
break;
}
switch(data_bit)
{
case 5:
bitclr(UCSR1C,UCSZ10);
bitclr(UCSR1C,UCSZ11);//5位数据位
break;
case 6:
bitset(UCSR1C,UCSZ10);
bitclr(UCSR1C,UCSZ11);//6位数据位
break;
case 7:
bitclr(UCSR1C,UCSZ10);
bitset(UCSR1C,UCSZ11);//7位数据位
break;
case 8:
bitset(UCSR1C,UCSZ10);
bitset(UCSR1C,UCSZ11);//8位数据位
break;
}
bitclr(UCSR1C,UCPOL1); //异步通信时将此位置为0
//配置串口通信///////////////////////////////////////////
//设置帧格式: 异步8个数据位1个停止奇校验
//UCSR1C = 0x36;//B00110110
//设置波特率
UBRR1H = 0X00;
UBRR1L = baud_set[i];
// 接收器与发送器使能
UCSR1B = (1<<RXEN1)|(1<<TXEN1);
break;
}
//UDR0=0x00;
}
void Usart_Send(unsigned char com_num,unsigned char data)
{//usart串口发送
switch(com_num)
{
case 0:
/* 等待发送缓冲器为空 */
while ( !( UCSR0A & (1<<UDRE0)) )
;
/* 将数据放入缓冲器,发送数据*/
UDR0 = data;
break;
case 1:
/* 等待发送缓冲器为空 */
while ( !( UCSR1A & (1<<UDRE1)) )
;
/* 将数据放入缓冲器,发送数据*/
UDR1 = data;
break;
}
}
unsigned char Usart0_Receive(void)
{//串口0接收
unsigned char receive_temp=0;
if(UCSR0A & (1<<RXC0))
receive_temp=UDR0;
return receive_temp;
}
unsigned char Usart1_Receive(void)
{//串口1接收
unsigned char receive_temp=0;
if(UCSR1A & (1<<RXC1))
receive_temp=UDR1;
return receive_temp;
}
unsigned char Usart_Receive(void)
{//usart串口接收
unsigned char receive_temp;
receive_temp=Usart0_Receive();
if(receive_temp) return receive_temp;
receive_temp=Usart1_Receive();
if(receive_temp) return receive_temp;
return 0;
}
//******************************************************************************
//*******************************TWI FUNCTION**********************************/
//******************************************************************************
void Twi_Init(void)
{//Twi口初始化
/* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
TWSR = 0;
TWBR = (F_CPU / 100000UL - 16) / 2;
}
int ee24xx_read_bytes(uint16_t eeaddr, int len, uint8_t *buf)
{//读EEPROM
uint8_t sla, twcr, n = 0;
int rv = 0;
/* patch high bits of EEPROM address into SLA */
sla = TWI_SLA_24CXX | (((eeaddr >> 8) & 0x07) << 1);
/*
* Note [8]
* First cycle: master transmitter mode
*/
restart:
if (n++ >= MAX_ITER)
return -1;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_REP_START: /* OK, but should not happen */
case TW_START:
break;
case TW_MT_ARB_LOST: /* Note [9] */
goto begin;
default:
return -1; /* error: not in start condition */
/* NB: do /not/ send stop condition */
}
/* Note [10] */
/* send SLA+W */
TWDR = sla | TW_WRITE;
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK: /* nack during select: device busy writing */
/* Note [11] */
goto restart;
case TW_MT_ARB_LOST: /* re-arbitrate */
goto begin;
default:
goto error; /* must send stop condition */
}
TWDR = eeaddr; /* low 8 bits of addr */
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error; /* must send stop condition */
}
/*
* Note [12]
* Next cycle(s): master receiver mode
*/
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send (rep.) start condition */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_START: /* OK, but should not happen */
case TW_REP_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
/* send SLA+R */
TWDR = sla | TW_READ;
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_MR_SLA_ACK:
break;
case TW_MR_SLA_NACK:
goto quit;
case TW_MR_ARB_LOST:
goto begin;
default:
goto error;
}
for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) /* Note [13] */;
len > 0;
len--)
{
if (len == 1)
twcr = _BV(TWINT) | _BV(TWEN); /* send NAK this time */
TWCR = twcr; /* clear int to start transmission */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_MR_DATA_NACK:
len = 0; /* force end of loop */
/* FALLTHROUGH */
case TW_MR_DATA_ACK:
*buf++ = TWDR;
rv++;
break;
default:
goto error;
}
}
quit:
/* Note [14] */
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */
return rv;
error:
rv = -1;
goto quit;
}
int ee24xx_write_bytes(uint16_t eeaddr, int len, uint8_t *buf)
{//写EEPROM
uint8_t sla, n = 0;
int rv = 0;
uint16_t endaddr;
// if (eeaddr + len < (eeaddr | (PAGE_SIZE - 1)))
// endaddr = eeaddr + len;
// else
// endaddr = (eeaddr | (PAGE_SIZE - 1)) + 1;
// len = endaddr - eeaddr;
endaddr=eeaddr+len-1;
/* patch high bits of EEPROM address into SLA */
sla = TWI_SLA_24CXX | (((eeaddr >> 8) & 0x07) << 1);
restart:
if (n++ >= MAX_ITER)
return -1;
begin:
/* Note [15] */
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_REP_START: /* OK, but should not happen */
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
return -1; /* error: not in start condition */
/* NB: do /not/ send stop condition */
}
/* send SLA+W */
TWDR = sla | TW_WRITE;
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK: /* nack during select: device busy writing */
goto restart;
case TW_MT_ARB_LOST: /* re-arbitrate */
goto begin;
default:
goto error; /* must send stop condition */
}
TWDR = eeaddr; /* low 8 bits of addr */
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error; /* must send stop condition */
}
for (; len > 0; len--)
{
TWDR = *buf++;
TWCR = _BV(TWINT) | _BV(TWEN); /* start transmission */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_NACK:
goto error; /* device write protected -- Note [16] */
case TW_MT_DATA_ACK:
rv++;
break;
default:
goto error;
}
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */
return rv;
error:
rv = -1;
goto quit;
}
//******************************************************************************
//*******************************内部EEPROM*************************************/
//******************************************************************************
unsigned char EEPROM_read(unsigned int uiAddress)
{//写内部EEPROM
while(EECR & (1<<EEWE)) //等待上一次写操作结束
;
EEAR = uiAddress; //设置地址寄存器
EECR |= (1<<EERE); //设置EERE以启动读操作
return EEDR; //自数据寄存器返回数据
}
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{//读内部EEPROM
while(EECR & (1<<EEWE)) //等待上一次写操作结束
;
EEAR = uiAddress; //设置地址和数据寄存器
EEDR = ucData;
EECR |= (1<<EEMWE); //置位EEMWE
EECR |= (1<<EEWE); //置位EEWE以启动写操作E
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -