这是一个通过串口来发送16位数据给SIP口来控制DA输出,我是个新手,刚开始编不久,最近写的这个程序,可能有错,请高手能指点下。
//ICC-AVR application builder : 2007-1-4 20:12:16
// Target : M16
// Crystal: 8.0000Mhz
#include
#include
#include
#define SIZE 100
void port_init(void);//端口初始化函数
void uart0_init(void);//M16串口初始化函数
void spi_init(void);//SPI端口初始化函数
void spi_stc_isr(void);//SPI端口中断函数
void init_devices(void);//整个设备初始化函数
void delay_1ms(void);//延时1ms程序
void delay(unsigned int n);//延时n毫秒程序
void putchar(unsigned char c); //字符输出函数
void puts(unsigned char *s);//字符串输出函数
void uart0_rx_isr(void);//串口接收中断函数
void chose_da(char);//DA选择函数
void trans_SPI(char DATA3);//SPI口的输出函数
unsigned char URX_data=0;//接收到数据
unsigned char SPI_rx_buffer[SIZE]; //SPI接收数据缓冲区
unsigned char SPI_tx_buffer[SIZE]; //SPI发送数据缓冲区
unsigned char rx_wr_index, rx_rd_index, rx_counter, rx_buffer_overflow;
unsigned char tx_wr_index ,tx_rd_index, tx_counter, SPI_ok;
void port_init(void) //端口初始化函数
{
PORTA = 0x00;
DDRA = 0x1F;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
void uart0_init(void) //M16串口初始化函数
{
UCSRB = 0x00; // 设置波特率前关闭中断
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;//异步模式,1位停止位,8位数据位,baud rate: 9600,无校验,baud rate:9615 (0.2%)
UBRRL = 0x33; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98; //发送允许、接收允许、接收中断允许
}
void spi_init(void) //SPI端口初始化函数
{
unsigned char temp;
DDRB |= 0x080; //MISO=input and MOSI,SCK,SS = output
PORTB |= 0x80; //MISO上拉电阻有效
SPCR = 0xD5; //SPI允许,主机模式,MSB,允许SPI中断,极性方式01,1/16系统时钟速率
SPSR = 0x00;
temp = SPSR;
temp = SPDR; //清空SPI,和中断标志,使SPI空闲
SPI_ok = 1;
}
#pragma interrupt_handler spi_stc_isr:11
void spi_stc_isr(void) //SPI中断函数
{
SPI_rx_buffer[rx_wr_index] = SPDR; //从ISP口读出收到的字节
SPI_ok = 1; // SPI 空闲
if (++rx_wr_index == SIZE) rx_wr_index = 0; //放入接收缓冲区,并调整队列指针
if (++rx_counter == SIZE)
{
rx_counter = 0;
rx_buffer_overflow = 1;
}
if (tx_counter) //如果发送缓冲区中有待发的数据
{
--tx_counter;
SPDR = SPI_tx_buffer[tx_rd_index]; //发送一个字节数据,并调整指针
if (++tx_rd_index == SIZE) tx_rd_index = 0;
SPI_ok = 0;
}
}
unsigned char getSPIchar(void) //SPI接收字节函数
{
unsigned char data;
while (rx_counter == 0); //无接收数据,等待
data = SPI_rx_buffer[rx_rd_index]; //从接收缓冲区取出一个SPI收到的数据
if (++rx_rd_index == SIZE) rx_rd_index = 0; //调整指针
CLI();
--rx_counter;
SEI();
return data;
}
void putSPIchar(char c) //SPI发送字节函数
{
while (tx_counter == SIZE);//发送缓冲区满,等待
CLI();
if (tx_counter || SPI_ok==0 ) //发送缓冲区已中有待发数据
{ //或SPI正在发送数据时
SPI_tx_buffer[tx_wr_index] = c; //将数据放入发送缓冲区排队
if (++tx_wr_index == SIZE) tx_wr_index = 0; //调整指针
++tx_counter;
}
else
{
SPDR = c; //发送缓冲区中空且SPI口空闲,直接放入SPDR由SIP口发送
SPI_ok = 0; //
}
SEI();
}
void init_devices(void) //整个设备初始化函数
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
spi_init();
uart0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void delay_1ms(void) //延时1ms程序
{
unsigned int i;
for(i=1;i
}
void delay(unsigned int n) //延时n毫秒程序
{
unsigned int i=0;
for(i=0;i
delay_1ms();
}
void putchar(unsigned char c) //字符输出函数
{
while (!(UCSRA&(1 << UDRE)));//判断上次发送有没有完成
UDR = c;
}
void puts(unsigned char *s) //字符串输出函数
{
while (*s)
{
putchar(*s);
s++;
}
}
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void) //串口接收中断函数
{
URX_data = UDR;
}
void main(void)
{
unsigned int dadata=0;//传送给SPI口的16位数据变量
unsigned char dacl=0;//传送的低8位数据
unsigned char dach=0;//传送的高8位数据
unsigned char DATA1=0;
init_devices();
SEI(); //开中断
while (1)
{
if ((URX_data&0xFF)==0x02)//关闭DA
{
PORTA=0x00;
puts("STOP_DA");
}
else if((URX_data&0xFF)==0x01)//复位DA
{
PORTA=0x01; //A40口输出低电平使DA复位
delay_1ms();
PORTA=0x00; //A40口输出高电平结束DA复位
puts("RSET_DA");
}
else //DA开始应用
{
puts("STAR_DA");
dacl=URX_data;//取低字节
dach=URX_data;//取高字节
putSPIchar(dacl);
putSPIchar(dach);
}
}
}