board_func.c
来自「在WinAVR下的ST7565圖形點陣的驅動程序」· C语言 代码 · 共 398 行
C
398 行
//包含所需头文件
#include "config.h"
/********************************************************************
** 系统初始化功能函数
********************************************************************/
//端口初始化
void port_init(void)
{
SFIOR &= ~BIT(PUD);
PORTA = 0x00;
DDRA = 0xE0;
PORTB = 0x00;
DDRB = 0xF6;
PORTC = 0x1E;
DDRC = 0xE1;
PORTD = 0x00;
DDRD = 0xE0;
}
//定时器T0初始化
void timer0_init(void)
{
TCCR0 = 0x00; // 停止定时器
TCNT0 = 0x00; // 初始值
OCR0 = TIMER0_DATA; // 比较匹配值
//OCR0 = 0x25; // 比较匹配值
TIMSK |= BIT(OCIE0); // 比较匹配中断允许
TCCR0 = 0x0F; // 启动定时器 Fosc/1024
}
//定时T1初始化
void timer1_init(void)
{
TCCR1B = 0x00; //停止定时器
TIMSK |= 0x20; //中断允许
TCNT1H = 0xFF;
TCNT1L = 0xFF; //初始值
OCR1AH = 0xFE;
OCR1AL = 0xFF; //匹配A值
OCR1BH = 0xFE;
OCR1BL = 0xFF; //匹配B值
ICR1H = 0xFF;
ICR1L = 0xFF; //输入捕捉匹配值
TCCR1A = 0x00;
TCCR1B = 0x83; //启动定时器
}
/********************************************************************
** SPI 底层功能函数
********************************************************************/
// SPI baud rate = 921.6KHz
void spi_init(void)
{
DDRB |= BIT(PORT1) | BIT(PORT2);
PORTB |= ~ BIT(PORT1) | BIT(PORT2);
//spi初始化
SPCR = BIT(SPE) | BIT(MSTR) | BIT(SPR0) | BIT(CPHA);
SPSR = 0x00;
}
//功能:使用SPI发送一个字节
void spi_write(uint8 sData)
{
//SPSR &= ~BIT(SPIF);
SPDR = sData;
while(!(SPSR & BIT(SPIF)));
//sData=SPDR;//读从机发回来的数据
}
//功能:使用SPI接收一个字节
uint8 spi_read(void)
{
SPDR = 0xFF;
while(!(SPSR & BIT(SPIF)));
return SPDR;
}
/********************************************************************
** TWI 底层功能函数
********************************************************************/
uint8 Twi_SLA;
void twi_SetBitrate(uint16 bitrateKHz)
{
uint8 bitrate_div;
/* set i2c bitrate*/
/* SCL freq = F_CPU / (16 + 2 * TWBR)) */
/* for processors with additional bitrate division (mega64) */
/* SCL freq = F_CPU/(16+2*TWBR*4^TWPS) */
/* set TWPS to zero */
TWSR = 0x00;
/* calculate bitrate division */
bitrate_div = ((F_CPU / 1000) / bitrateKHz);
if(bitrate_div >= 16) bitrate_div = (bitrate_div - 16) / 2;
TWBR = bitrate_div;
}
//TWI初始化函数
// SCL freq = 100KHz
void twi_init(void)
{
TWCR = 0x00; // 禁止TWI
twi_SetBitrate(100);
TWCR = BIT(TWEN); // 启动TWI | BIT(TWSTA)
}
//仲裁成为主机,发送START信号
//返回值: 0表示成功, 1表示失败
uint8 twi_start(void)
{
TWCR = BIT(TWINT) | BIT(TWEN) | BIT(TWSTA);
while(!(TWCR & BIT(TWINT)));
if((TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
return TW_ERROR;
return TW_OK;
}
//停止通信,发送STOP信号
void twi_stop(void)
{
TWCR = BIT(TWINT) | BIT(TWEN) | BIT(TWSTO);
while(!(TWCR & BIT(TWSTO)));
}
//发出从机地址与写命令,即SLA+W,进入MT模式
//返回值: 0表示成功, 1表示失败
uint8 twi_to_write(void)
{
TWDR = Twi_SLA & 0xFE;
TWCR = BIT(TWINT) | BIT(TWEN);
while(!(TWCR & BIT(TWINT)));
if(TW_STATUS != TW_MT_SLA_ACK)
return TW_ERROR;
return TW_OK;
}
//发出从机地址与读命令,即SLA+R,进入MR模式
//返回值: 0表示成功, 1表示失败
uint8 twi_to_read(void)
{
TWDR = Twi_SLA | 0x01;
TWCR = BIT(TWINT) | BIT(TWEN);
while(!(TWCR & BIT(TWINT)));
if(TW_STATUS != TW_MR_SLA_ACK)
return TW_ERROR;
return TW_OK;
}
//向从机发数据
//返回值: 0表示接到ACK, 1表示失败, 2表示接NOT ACK
uint8 twi_send(uint8 data)
{
TWDR = data;
TWCR = BIT(TWINT) | BIT(TWEN);
while(!(TWCR & BIT(TWINT)));
if(TW_STATUS == TW_MT_DATA_ACK)
return TW_OK;
else if(TW_STATUS == TW_MT_DATA_NACK)
return TW_NACK;
return TW_ERROR;
}
//接收从机发来的数据
//返回值: 0表示接到ACK, 1表示失败, 2表示接NOT ACK
uint8 twi_receive(uint8 *data)
{
TWCR = BIT(TWINT)| BIT(TWEN);
while(!(TWCR & BIT(TWINT)));
*data = TWDR;
if(TW_STATUS == TW_MR_DATA_ACK)
return TW_OK;
else if(TW_STATUS == TW_MR_DATA_NACK)
return TW_NACK;
return TW_ERROR;
}
//接收从机发来的数据
//返回值: 0表示接到ACK, 1表示失败, 2表示接NOT ACK
uint8 twi_SendAck(uint8 Ack)
{
if(Ack)
{
TWCR = BIT(TWINT)| BIT(TWEN) | BIT(TWEA);
}
else
{
TWCR = BIT(TWINT)| BIT(TWEN);
}
while(!(TWCR & BIT(TWINT)));
if(TW_STATUS == TW_MR_DATA_ACK)
return TW_OK;
else if(TW_STATUS == TW_MR_DATA_NACK)
return TW_NACK;
return TW_ERROR;
}
uint8 twi_WriteBuffer(uint8 SubAddr, uint8 *Buff, uint8 cnt, uint8 MemType)
{
uint8 error;
twi_start();
error = twi_to_write();
if(error) goto twi_Wr_exit;
error = twi_send(SubAddr);
if(error) goto twi_Wr_exit;
while(cnt--)
{
if(MemType)
error = twi_send(pgm_read_byte(*Buff ++));
else
error = twi_send(*Buff ++);
if(error) goto twi_Wr_exit;
}
twi_Wr_exit:
twi_stop();
return error;
}
uint8 twi_ReadBuffer(uint8 SubAddr, uint8 *Buff, uint8 cnt)
{
uint8 error;
twi_start();
error = twi_to_write();
if(error) goto twi_Rd_exit;
error = twi_send(SubAddr);
if(error) goto twi_Rd_exit;
twi_stop();
twi_start();
error = twi_to_read();
if(error) goto twi_Rd_exit;
while(--cnt)
{
twi_receive(Buff++);
twi_SendAck(1);
}
twi_receive(Buff++);
twi_SendAck(0);
twi_Rd_exit:
twi_stop();
return error;
}
/********************************************************************
** UART 底层功能函数
********************************************************************/
#ifdef USE_UART0
// 使用串口UART0
//串口通信初始化
void usart_init(void)
{
UCSR0B = 0x00;//禁止中断
UCSR0A = 0x00;
UCSR0C = 0x06;
UBRR0L = UBRR_VALUE & 0xFF;
UBRR0H = UBRR_VALUE / 0xFF;
UCSR0B = BIT(RXEN0) | BIT(TXEN0) | BIT(RXCIE0);
UDR0 = 0x00;
}
uint8 Uart_SendChar(uint8 iData)
{
while (!(UCSR0A & BIT(UDRE0))); /* Wait until transmit is complete */
UDR0 = iData;
return iData;
}
uint8 Uart_RecvByte(void)
{
return UDR0;
}
#else
// 使用串口UART1
//串口通信初始化
void usart_init(void)
{
UCSR1B = 0x00;//禁止中断
UCSR1A = 0x00;
UCSR1C = 0x06;
UBRR1L = UBRR_VALUE & 0xFF;
UBRR1H = UBRR_VALUE / 0xFF;
UCSR1B = BIT(RXEN1) | BIT(TXEN1) | BIT(RXCIE1);
UDR1 = 0x00;
}
uint8 Uart_SendChar(uint8 iData)
{
while (!(UCSR1A & BIT(UDRE1))); /* Wait until transmit is complete */
UDR1 = iData;
return iData;
}
uint8 Uart_RecvByte(void)
{
return UDR1;
}
#endif
void Uart_SendSeq(uint8 *string, uint8 Len)
{
unsigned char i;
for(i=0; i<Len; i++)
{
Uart_SendChar(*string++);
}
}
uint8 MakeChecksum(uint8 *buff, uint8 BufLen)
{
uint8 i, result=0 ;
for(i=0; i<BufLen; i++)
{
result += buff[i];
}
result = (~result)+1 ;
return (result);
}
/********************************************************************
** 系统初始化总函数
********************************************************************/
void init_devices(void)
{
cli(); // 禁止所有中断
wdt_disable();
MCUCR = 0x00;
//MCUCSR = 0x80;// 禁止JTAG
//GICR = 0x00;
port_init();
timer0_init();
timer1_init();
spi_init();
twi_init();
usart_init();
sei(); // 开全局中断
}
uint16 volatile Delay_Timer;
void Delay_10ms(uint16 Delay)
{
Delay_Timer = Delay;
do{
NOP();
sleep_mode();
NOP();
} while(Delay_Timer > 0);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?