微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 有偿急求PIC18F46K80CAN串口程序

有偿急求PIC18F46K80CAN串口程序

时间:10-02 整理:3721RD 点击:

本人PIC菜鸟,最近使用PIC18F46K80单片机做项目。通过改串口波特率的寄存器来调整波特率,但无论寄存器赋什么值,波特率都不变,串口波特率一直是9600。现有偿求串口程序,要求:
1.写详细注释。
2.串口波特率可调,最少可在三个速率下运行。通过宏定义可设置串口波特率。波特率设置好后,可通过串口调试助手进行调试。
3.酬劳300RMB,先发代码,通过串口调试助手调试成功后转账。视代码质量可增加酬谢金额。
4.qq:704308037,如有意可加qq详谈。
求各位pic大神相助,万分感谢。

16的玩过;18的CAN没玩过,给个别人的例子你;
        //pic18f248 CAN总线发送接收子程序
//同样可以用在pic18系列带CNA模块的MCU 中。
        #define 0xcc  MyAddrID
//--------------------------------------------------------
       
        void InitializeCanModel(void)
{
TRISB = TRISB | 0X08;  //必须确保TRISB<3> 位置1。
//---------------------------------------------------------------
//在本程序中只用Buffer0 进行发送。
TXB0CONbits.TXPRI1 = TXB0CONbits.TXPRI0 = 1;   // 设置TX Buffer0 为最高发送优先级
TXB1CONbits.TXPRI1 = TXB1CONbits.TXPRI0 = 0;   // 设置TX Buffer1 为最低发送优先级
TXB2CONbits.TXPRI1 = TXB2CONbits.TXPRI0 = 0;   // 设置TX Buffer2 为最低发送优先级
CIOCON = 0X20;    //temp test
       
        //----------------------------------------------------------------
//只有在配置模式下,才能对下列的寄存器进行修改。
//? CNF1, CNF2, CNF3
//? 接收滤波寄存器
//? 接收屏蔽寄存器
CANCON = 0X80;            // Set to Configuration Mode.
while(CANSTAT !=0X80);    //No. Continue to wait...
//-----------------------------------------------------------------
//位定时配置寄存器1
//;     Fosc = 16MHz
//;     BRP        =   7  (divide by 8)
//;     Sync Seg   = 1TQ
//;     Prop Seg   = 1TQ
//;     Phase Seg1 = 3TQ
//;     Phase Seg2 = 3TQ
//;  TQ = 2 x (BRP + 1) / FOSC= 2*8/16M= 1/1M
//;    TQ = 2 * (1/Fosc) * (BRP+1)
//;     Bus speed = 1/(Total # of TQ) * TQ    125k
//CNF1 = 0X2A;  00 = 长度= 1xTQ
       
        BRGCON1 = 0X07;     //位定时配置寄存器1
//------------------------------------------------------------------
//- 配置寄存器2 ( 地址:29h)
//R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
//BTLMODE SAM PHSEG12 PHSEG11 PHSEG10 PRSEG2 PRSEG1 PRSEG0
//bit 7 bit 0
//bit 7 BTLMODE: 相位段2 位时间长度
//1 = 相位段2 位时间长度由CNF3 中的PHSEG22:PHSEG20 确定
//bit 6 SAM: 采样点配置
//0 = 在采样点对总线进行一次采样
       
        //bit 5-3 PHSEG1<2:0>:相位段1 位时间长度
//(PHSEG1 + 1) x TQ = 2/1M
       
        //bit 2-0 PRSEG<2:0>:传播段长度
//(PRSEG + 1) x TQ = 1/1M
       
        BRGCON2 = 0X90;
//--------------------------------------------------------------------
//;#define PHSEG2_3TQ      0x02
//   WAKFIL   0 = 唤醒输入引脚滤波禁止
//2:0>:相位段2 长度
//(PHSEG2 + 1) x TQ
BRGCON3 = 0x02;
       
        //--------------------------------------------------------------------
//pic18f248 采用三个发送缓冲器。每个发送缓冲器占据14 字节的SRAM。
//*********************************************
//设置RX0 ,RX1 的滤波reg和屏蔽reg。
// pic18f2480有2个接收缓冲区。
//第一个接收缓冲区有1个屏蔽寄存器RXM0和2个过滤寄存器 RXF0,RXF1;
//第二个接收缓冲区有1个屏蔽寄存器RXM1 和5个滤波寄存器 RXF2,RXF3,RXF4,RXF5;
//一旦MAB 接收到有效报文,报文中的标识符字段将与过滤寄存器中的值进行比较。如果两者匹配,该报文将被载入相应
// 的接收缓冲器。
//*********************************************
//设置buffer0的屏蔽寄存器和滤波寄存器
//屏蔽寄存器主要确定对标识符中的哪一位进行滤波。如果某屏蔽位设置为零,对应的标识符位将被自动接收而不被滤波。
RXM0SIDH = 0xFF;             // 屏蔽寄存器 N 标准标识符的高位
RXM0SIDL = 0XFF;             // 屏蔽寄存器 N 标准标识符的低位
//----------------------------------------------------------------------
//接收到的标识符中每一位是如何与验收屏蔽器和滤波器进行比较, 以确定该报文是否应被载入接收缓冲器
//只对MyAddrID进行接收。别的一律过滤去。
//因为地址是11位,但是数量有限,只用8位就够了。
RXF0SIDH = MyAddrID;    //只用到一个字节,8位。  验收滤波寄存器 N 标准标识符的高位
RXF0SIDL = 0;     
//-----------------------------------------------------------------------      
RXF1SIDH = 0XFF;            //第一缓冲区的第二滤波器不用。
RXF1SIDL = 0xff;  
//------------------------------------------------------------------------
       
        RXB0CONbits.RXM1 =1;  //0;         //只接收符合滤波器条件的带标准标识符的有效报文
RXB0CONbits.RXM0 =1;
//RXB0CONbits.RXBODBEN =0;     //禁止滚存
   
//-----------------NO USE
RXM1SIDH = 0xFF;             //屏蔽reg。
RXM1SIDL = 0XFF;
RXF2SIDH = 0XFF;             //对接收缓冲区的屏蔽寄存器和滤波寄存器设置
RXF2SIDL = 0;  
RXF3SIDH = 0XFF;
RXF3SIDL = 0;  
RXF4SIDH = 0XFF;   
RXF4SIDL = 0;  
RXF5SIDH = 0XFF;   
RXF5SIDL = 0;  
       
        CANCON = CANCON & 0x1F;              // Set to Normal mode
while( CANSTAT& 0xE0);               //等待 器件处于正常工作模式
//---------------------------------------------------------------------
PIE3 = PIE3 | 0X05 ;             // TXB0IE:CAN 发送缓冲器 0 中断允许位. (允许发送缓冲器0 中断;允许接收缓冲器0中断)
PIR3 = 0 ;                       //CAN 发送缓冲器0 中断标志位.
IPR3 = IPR3 | 0X05;              // 把发送缓冲器0和接收缓冲器0  定为最高优先级。
       
        }
       
        /*************************************************
程序名:CanTransmit
功能:把TransData[0~7]中的数据发出去。
     发送地址是addr
**************************************************/
void CanTransmit(void)   //
{
Flags.CanTx0Ok = 0;
ClrWdt();
AgainTrans:
TXB0SIDH = addr;    //设置标识苻。(别人的地址)
TXB0SIDL = 0  ;     //报文将发送标准标识符
TXB0DLC  = 0x08;    ////发送的报文为数据帧,设定发送的数据长度8 字节
TXB0D0 = TransData[0];    ///设置8个字节的内容
TXB0D1 = TransData[1];
TXB0D2 = TransData[2];
TXB0D3 = TransData[3];
TXB0D4 = TransData[4];
TXB0D5 = TransData[5];
TXB0D6 = TransData[6];
TXB0D7 = TransData[7];
       
        TXB0CONbits.TXREQ = 1;     // 启动发送。
while(TXB0CONbits.TXREQ);   // 缓冲器有没有报文正在发送,有,等待。
       
        }
       
        /*******************************************************
程序名:CheckCanMsg
出口参数:0  没有接收到报文
          9  有报文,且正确。
       
        作用:检查接收缓冲区0 是否接收到报文,如果有则把报文内容放到
      RecData[]中。
       
        ********************************************************/
unsigned char  CheckCANMsg (void)
{
unsigned char bRecCount,iRecID_H,iRecID_L;
if (RXB0CONbits.RXFUL ==0) return(0);     // 没有接收到报文,返回。
if (RXB0CONbits.FILHIT0 ==1) return(1);  // 只接收接收缓冲区中的0号滤波器验收的数据。
if (COMSTATbits.RXB0OVFL ==1) return(2); // 如果0号接收缓冲区溢出,返回
if (Flags.CanRx0Ok ==1)
{ Flags.CanRx0Ok = 0;
RXB0CONbits.RXFUL=0;
     iRecID_H = RXB0SIDH;             //接收到标识苻,基本没有用,如果标识苻不对,也不会接收。
     if (RXB0SIDH == MyAddrID)
   {  
       iRecID_L = RXB0SIDL & 0xE0;
       bRecCount = RXB0DLC & 0x0F;       //数据的长度
       //RXF0SIDH
      RecData[0] = RXB0D0;
   RecData[1] = RXB0D1;
   RecData[2] = RXB0D2;
   RecData[3] = RXB0D3;
   RecData[4] = RXB0D4;
   RecData[5] = RXB0D5;
   RecData[6] = RXB0D6;
   RecData[7] = RXB0D7;
   return(9);
   }
  else
   return(3);
}
       
        }
       
        /***********************************调试笔记**************************************************************************
1)设置好并打开发送中断,发送一帧后,如果发送中断发生,说明发送端正常发出,并且接收端工作正常,
已接收到总线上的帧并且回复了ACK。(没有ACK,发送中断是不会发生的。)
2)帧格式有标准帧和扩展帧,本程序用的是标准帧。11位标识符。
3)11位标识符的7个最高位不能全是隐性的。
                4)PIC18F248 有3个发送缓冲区和2个接收缓冲区。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top