搜索
bottom↓
回复: 2

晒晒我的 Mega88 串口程序与 IO 位操作的"绝招"【恢复】

[复制链接]

出0入0汤圆

发表于 2008-12-31 10:45:45 | 显示全部楼层 |阅读模式
程序是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周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2008-12-31 10:57:44 | 显示全部楼层
呵呵,不好意思,发到"开源充电器"版面了



请版主帮忙移至AVR版面.谢谢了!

出0入0汤圆

发表于 2009-2-5 11:01:01 | 显示全部楼层
MARK
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 10:04

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表