|
程序是03年用M8时写的(那个时候记得AVR出M8还没有多久)
现在已经改为M88的GCC程序. 虽然程序不算高明, 但还是希望能让部分人得益.就当我个人经验的发表吧!
先说说 IO 位操作的"绝招",我用一个 BitType.h 定义了这些宏.
//////////////////////////////////////
// BitType.h
// Jacky.L
#define H(port,bitvalue) port |=(bitvalue) //置1
#define L(port,bitvalue) port &=~(bitvalue) //置0
#define N(port,bitvalue) port ^=(bitvalue) //取反
#define BIT(x) (1<<x)
#define B0 (1<<0)
#define B1 (1<<1)
#define B2 (1<<2)
#define B3 (1<<3)
#define B4 (1<<4)
#define B5 (1<<5)
#define B6 (1<<6)
#define B7 (1<<7)
#define CLI() L(SREG,B7)
#define SEI() H(SREG,B7)
#define uchar unsigned char
#define uint unsigned short int
#define ulong unsigned long int
#define UINT unsigned short int
#define DWORD unsigned long int
// BitType.h (end)
///////////////////////////////////////
使用方法很简单.
比如某串行器件有CS,SCK,DATA引脚,
#define CNTL_PORT PORTD //用PORTD 控制
#define _CS B0 //bit0
#define _SCK B1 //bit1
#define _DATA B2 //bit2
....
H(CNTL_PORT,_SCK); //_SCK set to 1
L(CNTL_PORT,_SCK | _CS); //_SCK and _CS set to 0
当然还可以对寄存器进行类似的操作.
/*************************************************
//以下是USART通迅的程序模块:
// GCC code
// Jacky.L
// USART.c
// 接收区使用循环指针,这样CPU有空时就读取缓冲区,FIFO功能.
**************************************************/
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "BitType.h"
#define ILEN 256 //接收数据缓冲区的个数
#define inbufsign 0x01 //接收缓冲区非空
#define inbufful 0x02 //接收缓冲区满
uchar UsartSta;
uchar UsartBuffer[ILEN]; //Max Buffer data=256
uchar *BufferCountUse=UsartBuffer; //Use for USART Receiving SUB Program Pointer.
uchar *BufferINT=UsartBuffer; //interrupt SUB Program Pointer.
uchar ch; //regester for RXT data.
ISR(USART_RX_vect)
{
uchar i;
if(!(UsartSta&inbufful)){
*BufferINT=UDR0;
BufferINT++;
UsartSta|=inbufsign;
if (BufferINT==UsartBuffer+ILEN) BufferINT=UsartBuffer; //地址到顶部回到底部
if (BufferINT==BufferCountUse) UsartSta|=inbufful; //接收缓冲区满置满标志
}
else i=UDR0; //释放接收完成标志RXC
}
uchar getbyte (void)
{
if (!(UsartSta&inbufsign)) return 0;
CLI();
ch= *BufferCountUse; //取数据
BufferCountUse++; //最后取走的数据位置加一
UsartSta&=~inbufful; //输入缓冲区的满标志清零
if (BufferCountUse==UsartBuffer+ILEN) BufferCountUse=UsartBuffer; //地址到顶部回到底部
if (BufferCountUse==BufferINT) UsartSta&=~inbufsign; //地址相等置接收缓冲区空空标志,再取数前要检该标志
SEI();
return 1; //取回数据
}
void putchar_(uchar c)
{
while ( !( UCSR0A & (1<<UDRE0)) );
UDR0=c; //sent data
}
void puts_(const uchar *s)
{
while(*s)
{
putchar_(*s);
s++;
}
}
void uart_init(void)
{
CLI();
UCSR0B=(1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0); //enable receive and send and RXD_interrupt
//UBRRL=(fosc/16/(baud+1))%256;
//UBRRH=(fosc/16/(baud+1))/256;
UBRR0L=12; //default Baud Rate=4800
UBRR0H=0;
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00); //data_bit=8,stop_bit=1;
SEI(); //开放中断位。
}
void uart_close(void)
{ UCSR0B=0;}
//used sample:
void main(void)
{
uart_init();
puts_("Atmega88"); //send string "Atmega88" out
while(1)
{
if(getbyte ())
{
???=ch; //when receive data to ??? saving
}
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|