📄 app.c
字号:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <stdio.h>
#include "../TinyWorks.h"
#include "../port.h"
#include "../fifo.h"
TW_TCB TaskBatt_tcb; // 电池充电任务
TW_TCB TaskComm_tcb; // SPI通讯任务
// 任务堆栈
Stk_t TaskBatt_Stk[100];
Stk_t TaskComm_Stk[100];
// 电压数据缓冲区
volatile u16 MasterPower_Buff[8];
volatile u16 SlavePower_Buff[8];
volatile u16 MasterPower_r; // 主电源滤波后的AD值
volatile u16 SlavePower_r; // 备用电源滤波后的AD值
volatile u16 MasterPower; // 主电源电压,有一位小数
volatile u16 SlavePower; // 备用电源电压,有一位小数
volatile u8 PowerIndex=0;
// 通讯缓冲区
// rilo: remote inupt local output, remote is host
// roli: remote output local input, remote is host
volatile u8 RILO_Buffer[128];
volatile u8 ROLI_Buffer[128];
fifo_t rilo;
fifo_t roli;
u16 WorkState; // 主工作状态
u16 InternalState; // 内部工作状态
void uart0_init(void);
void adc_init(void);
void SPIReadVoltage( void );
void SPISendUARTData( void );
void SPIReceUARTData( void );
void SPIWriteEEPROM( void );
void SPIReadEEPROM( void );
void SPIReadState( void );
void init_hw( void )
{
DDRB = _BV(0) | _BV(1) | _BV(4);
PORTB = _BV(1);
DDRC = _BV(0) | _BV(1) | _BV(2) | _BV(3) | _BV(4) | _BV(5);
PORTC = _BV(0) | _BV(1) | _BV(2) | _BV(3) | _BV(4) | _BV(5);
DDRD = _BV(1) | _BV(2) | _BV(3) | _BV(4) | _BV(5) | _BV(6);
PORTD = _BV(3) | _BV(4) | _BV(5) | _BV(6);
SPCR = _BV(6) | _BV(7);
uart0_init();
adc_init();
}
ISR(SPI_STC_vect)
{
SPCR = _BV(6); // 禁止SPI中断
switch(SPDR)
{
case 0x01: // 读主、备电源电压
SPIReadVoltage();
break;
case 0x02: // 串口发送数据
SPISendUARTData();
break;
case 0x03: // 串口接收数据
SPIReceUARTData();
break;
case 0x04: // 写EEPROM
SPIWriteEEPROM();
break;
case 0x05: // 读EEPROM
SPIReadEEPROM();
break;
case 0x06: // 读工作状态
SPIReadState();
break;
default:
break;
}
SPCR = _BV(6) | _BV(7);
//byte in SPDR has been sent/received
}
void TimerHook( void )
{
if ((ADMUX&0x0F)== 0x07)
{
ADMUX &= ~_BV(0);
}
else
{
ADMUX |= _BV(0);
}
ADCSRA |= _BV(6);
}
ISR(ADC_vect)
{
volatile u16 value;
value = ADC;
if ((ADMUX&0x0F)== 0x07)
{
MasterPower_Buff[PowerIndex] = value;
}
else
{
SlavePower_Buff[PowerIndex] = value;
PowerIndex ++;
}
if (PowerIndex == 8)
{
u16 i;
value = 0;
for(i=0; i<8; i ++)
{
value += MasterPower_Buff[i];
}
value >>= 3;
MasterPower_r = value;
value = 0;
for(i=0; i<8; i ++)
{
value += SlavePower_Buff[i];
}
value >>= 3;
SlavePower_r = value;
PowerIndex = 0;
}
}
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x47; //select adc input 0
ACSR = 0x80;
ADCSR = 0xCF;
}
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x02;
UCSRC = 0x86;
UBRRL = 0x67; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
ISR(USART_RXC_vect)
{
volatile u8 c;
c = UDR;
fifo_add(&roli, c);
fifo_add(&rilo, c);
}
ISR(USART_UDRE_vect)
{
PORTD |= _BV(2); // RS485置为发送状态
if (fifo_dummy(&rilo) == false)
{
u16 To=0;
UCSRB &= ~_BV(5); // 关发送中断
sei();
UCSRA |= ~_BV(6);
while(!(UCSRA&_BV(6)))
{
To ++;
if (To>1000)
{
break;
}
wdt_reset(); // 等待数据发送完毕
}
PORTD &= ~_BV(2); // RS485置为输入
return;
}
UDR = fifo_get(&rilo); // 发送一个字节的数据
}
void test_send( s8 *str )
{
while(*str)
{
fifo_add(&rilo, *str);
str ++;
}
UCSRB |= _BV(5);
}
s8 strt[20];
void TaskBatt( void )
{
volatile u16 loc_val;
for(;;)
{
cli();
loc_val = MasterPower_r;
sei();
loc_val *= 45;
loc_val /= 128;
cli();
MasterPower = loc_val;
sei();
sprintf(strt, "Master Power is %d.%dV\xd\xa", loc_val/10, loc_val%10);
test_send(strt);
cli();
loc_val = SlavePower_r;
sei();
loc_val *= 45;
loc_val /= 128;
cli();
SlavePower = loc_val;
sei();
sprintf(strt, "Slave Power is %d.%dV\xd\xa", loc_val/10, loc_val%10);
test_send(strt);
TWDelay(270);
PORTD ^= _BV(5);
wdt_reset();
}
}
void TaskComm( void )
{
TIMSK = 0x01;
PORTD &= ~_BV(2);
for(;;)
{
TWDelay(600);
PORTD ^= _BV(6);
wdt_reset();
if(fifo_dummy(&rilo) == true)
{
UCSRB |= _BV(5);
}
// test_send();
}
}
u8 WaitSPI( u16 TO )
{
TO <<= 11; // 按1个循环4条指令计算
while(TO)
{
if (SPSR&_BV(7))
return true;
TO --;
}
return false;
}
void SPIReadVoltage( void )
{
volatile u8 loc_reg;
SPDR = 0x81; // 返回命令
if (WaitSPI(8)==false)
return;
loc_reg = SPDR;
SPDR = MasterPower;
if (WaitSPI(2)==false)
return;
loc_reg = SPDR;
SPDR = MasterPower>>8;
if (WaitSPI(2)==false)
return;
loc_reg = SPDR;
SPDR = SlavePower;
if (WaitSPI(2)==false)
return;
loc_reg = SPDR;
SPDR = SlavePower>>8;
}
void SPISendUARTData( void )
{
volatile u8 loc_reg, loc_loop;
InternalState |= 0x01; // 置上发送数据标志
SPDR = 0x81; // 返回命令
if (WaitSPI(8)==false)
return;
loc_loop = SPDR;
SPDR = loc_loop;
for(;loc_loop!=0; loc_loop--)
{
if (WaitSPI(2)==false)
return;
loc_reg = SPDR;
fifo_add(&rilo, loc_reg);
SPDR = loc_reg;
}
}
void SPIReceUARTData( void )
{
volatile u8 loc_reg, loc_loop;
InternalState |= 0x01; // 置上发送数据标志
SPDR = 0x81; // 返回命令
if (WaitSPI(8)==false)
return;
loc_loop = SPDR;
if (loc_loop>fifo_len(&roli)) // 没收到那么多的数据
{
loc_loop = fifo_len(&roli);
}
SPDR = loc_loop;
for(;loc_loop!=0; loc_loop--)
{
if (WaitSPI(2)==false)
return;
loc_reg = SPDR;
SPDR = fifo_get(&roli);
}
}
void SPIWriteEEPROM( void )
{}
void SPIReadEEPROM( void )
{}
void SPIReadState( void )
{}
int main( void )
{
asm("cli");
rilo.len = 128;
rilo.in = 0;
rilo.out = 0;
rilo.buff = RILO_Buffer;
roli.len = 128;
roli.in = 0;
roli.out = 0;
roli.buff = ROLI_Buffer;
_delay_ms(100);
_delay_ms(100);
_delay_ms(100);
_delay_ms(100);
_delay_ms(100);
wdt_disable();
init_hw();
timer0_init();
TWInit();
TWCreate(&TaskBatt_tcb, TaskBatt, (Stk_t*)&TaskBatt_Stk[99], 6);
TWCreate(&TaskComm_tcb, TaskComm, (Stk_t*)&TaskComm_Stk[99], 1);
wdt_enable(WDTO_2S);
TWStart();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -