at91sam7x256之串口uart0设置之二

来源:互联网 发布:第5次人口普查的数据 编辑:程序博客网 时间:2024/05/01 22:10

搞了两天,at91sam7x256之串口uart0终于搞定了,

一开始出现的问题是发送出来的数据不对,但是用串口调试助手给开发板发送数据,然后直接回送没有问题。

原因是串口波特率设置不对,我把晶振频率FOSC作为系统主时钟MCK用了,虽然检查半天控制寄存器US_CR和模式寄存器US_MR各个位的值设置都没有问题,也是不行的。

看了开发板例程中的board .h头文件,我才知道原来晶振频率FOSC作为系统主时钟MCK不同:

#define AT91B_MAIN_OSC        18432000               // Main Oscillator MAINCK
#define AT91B_MCK             ((18432000*73/14)/2)   // Output PLL Clock

波特率问题就这样搞定了,可是还是有问题:

发送0x55,串口调试助手收到0xaa
发送0xbb,串口调试助手受到0xdd
这个问题也是灵机一动,这么有规律的错误,肯定是那个寄存器设置有点问题,

原来我把US_MR中US_MSBF设置了【高位在前地位在后】的发送,去掉这个US_MSBF设置使用默认的【低位在前高位在后】就可以了。

又解决一个问题,下功夫,就有收获啊。

代码都好了,贴出来以后还能用。

//UART0.H文件内容


extern AT91S_AIC * pAIC;
 void SendChar(unsigned char CH);
 void Init_UART0();

//UART0.C文件内容

#include <AT91SAM7X256.H>
#include "UART0.H"
#define  Fosc 18432000
#define AT91B_MAIN_OSC        18432000               // Main Oscillator MAINCK
#define AT91B_MCK             ((18432000*73/14)/2)   // Output PLL Clock
AT91PS_PIO    GPIO_A=AT91C_BASE_PIOA;
AT91PS_USART  UART0 =AT91C_BASE_US0;
//----------------------------------------
AT91S_AIC * pAIC=AT91C_BASE_AIC;
unsigned char DacContralBuff[16];
//----------------------------------------
void SendChar(unsigned char CH)
{
   while(!(UART0->US_CSR&0X02));
     UART0->US_THR=CH;
}
//----------------------------------------
unsigned char GetChar()
{
 unsigned char ch;

 return ch;
}
//-----------------------------------------
__irq void Usart0ISR(void)
{
 *AT91C_AIC_ICCR|=(1 << AT91C_ID_US0);
 if(UART0->US_CSR&0X01)
 {
  DacContralBuff[0]=UART0->US_RHR&0xff;
  SendChar(DacContralBuff[0]);
 }
 *AT91C_AIC_EOICR = 0X00; 
}
//=================
__inline unsigned int AT91F_US_Baudrate (
 const unsigned int main_clock, // /arg peripheral clock
 const unsigned int baud_rate)  // /arg UART baudrate
{
 unsigned int baud_value = ((main_clock*10)/(baud_rate * 16));
 if ((baud_value % 10) >= 5)
  baud_value = (baud_value / 10) + 1;
 else
  baud_value /= 10;
 return baud_value;
}

//*----------------------------------------------------------------------------
//* /fn    AT91F_US_SetBaudrate
//* /brief Set the baudrate according to the CPU clock
//*----------------------------------------------------------------------------
__inline void AT91F_US_SetBaudrate (
 AT91PS_USART pUSART,    // /arg pointer to a USART controller
 unsigned int mainClock, // /arg peripheral clock
 unsigned int speed)     // /arg UART baudrate
{
 //* Define the baud rate divisor register
 pUSART->US_BRGR = AT91F_US_Baudrate(mainClock, speed);
}

//*----------------------------------------------------------------------------
//* /fn    AT91F_US_SetTimeguard
//* /brief Set USART timeguard
//*----------------------------------------------------------------------------
__inline void AT91F_US_SetTimeguard (
 AT91PS_USART pUSART,    // /arg pointer to a USART controller
 unsigned int timeguard) // /arg timeguard value
{
 //* Write the Timeguard Register
 pUSART->US_TTGR = timeguard ;
}
//=================
void Init_UART0()
{
 unsigned int temp=0;
 GPIO_A->PIO_PER =0XfFFFFFFF;
 GPIO_A->PIO_OER=0X03;//PA0,PA1设置为输出 
 GPIO_A->PIO_SODR =0X03; //设置为高
 *AT91C_PMC_PCER = (unsigned int)1<<AT91C_ID_US0;                  //允许US0口的时钟
 GPIO_A->PIO_PDR =0x03; //设为外设
 GPIO_A->PIO_ASR =0X03; //设为外设A
 
 
 UART0->US_CR|= AT91C_US_RSTRX |          /* Reset Receiver      */
                   AT91C_US_RSTTX |          /* Reset Transmitter   */
                   AT91C_US_RXDIS |          /* Receiver Disable    */
                   AT91C_US_TXDIS;           /* Transmitter Disable */
 
// UART0->US_MR=0X108C0; //主时钟,8位数据,一位停止位,无校验 ,高位在前,异步模式
 UART0->US_MR=AT91C_US_USMODE_NORMAL |  /* Normal Mode */
                  AT91C_US_CLKS_CLOCK    |  /* Clock = MCK */
                  AT91C_US_CHRL_8_BITS   |  /* 8-bit Data  */
                  AT91C_US_PAR_NONE      |  /* No Parity   *///OVER=1 溢出错误
                  AT91C_US_NBSTOP_1_BIT  ;
      //|AT91C_US_MSBF;    /* 1 Stop Bit  */ //SYNC=0异步 SYNC=1同步
//异步模式 波特率=MCK/16/BRD或MCK/8/BRD;同步为波特率=MCK/BRD
 UART0->US_BRGR=AT91F_US_Baudrate(AT91B_MCK,9600);// (Fosc/(9600*16)); //AT91B_MCK
// UART0->US_BRGR|=Fosc/(9600*16)<<8;        
 UART0->US_CR=0X50;
 UART0->US_CR  |= AT91C_US_RXEN  |          /* Receiver Enable     */
                     AT91C_US_TXEN;            /* Transmitter Enable  */

 
 //UART0->US_IDR=0;
 //UART0->US_CSR//通道状态寄存器 2-发送状态,1-接收状态
 /* Setup Usart Interrupt Mode and Vector with Priority 7 and Enable it */
//   pAIC->AIC_SMR[AT91C_ID_US1] = 5;//设置触发模式和优先级7等级最高
   pAIC->AIC_SMR[AT91C_ID_US0] = 6; //双串口中断方式接收数据需设优先级
   UART0->US_IER =AT91C_US_RXRDY; //接收中断使能
//   pUSART1->US_IER =AT91C_US_RXRDY;
   pAIC->AIC_SVR[AT91C_ID_US0] = (unsigned long) Usart0ISR;//串口0中断地址放入向量表
//   pAIC->AIC_SVR[AT91C_ID_US1] = (unsigned long) Usart1ISR;//串口1中断地址放入向量表
   pAIC->AIC_IECR |=(1 << AT91C_ID_US0)|(1 << AT91C_ID_US1);//串口中断使能
 UART0->US_IER=0X01;  //接受中断使能 

 
 
}

//main。c文件内容

#include <AT91SAM7X256.H>
#include "UART0.H"

#define LED1 (1<<18)
#define LED2 (1<<20)
#define LED3 (1<<22)
#define LED4 (1<<24)
#define Key1 (1<<19)
#define Key2 (1<<21)
#define Key3 (1<<23)
#define Key4 (1<<25)


AT91PS_PIO GPIO_B=AT91C_BASE_PIOB;

void delay(unsigned  long msec)
{
    while(msec--);
}
void LED_Display()
{
  GPIO_B->PIO_SODR|=LED1;
  delay(0xffff);
  GPIO_B->PIO_SODR|=LED2;
  delay(0xffff);
  GPIO_B->PIO_SODR|=LED3;
  delay(0xffff);
  GPIO_B->PIO_SODR|=LED4;
  delay(0xffff);
  GPIO_B->PIO_CODR|=LED1;
  delay(0xffff);
  GPIO_B->PIO_CODR|=LED2;
  delay(0xffff);
  GPIO_B->PIO_CODR|=LED3;
  delay(0xffff);
//  GPIO_B->PIO_CODR|=LED4;
  delay(0xffff);
}
/****************************************************************************
* 文件名:Init_GPIO()
* 功  能:初始化GPIO
*       
* 说  明:
****************************************************************************/ 
void Init_GPIO()
{
 GPIO_B->PIO_OER|=LED1;
     GPIO_B->PIO_OER|=LED2;
      GPIO_B->PIO_OER|=LED3;
       GPIO_B->PIO_OER|=LED4;
 GPIO_B->PIO_OER=0x7fffffff;
 GPIO_B->PIO_SODR=0x7fffffff;
 *AT91C_PMC_PCER|=0x08;
}
void AT91F_LowLevelInit(void)

  {

    unsigned char i;

// 1 Wait State necessary to work at 48MHz

    AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS;     

    /////////////////////////////////////////////////////////////////////////////////////////////////////

    // Init PMC Step 1. Enable Main Oscillator 使能主振荡时钟

    // Main Oscillator startup time is board specific:

    // Main Oscillator Startup Time worst case (3MHz) corresponds to 15ms (0x40 for AT91C_CKGR_OSCOUNT field)

    /////////////////////////////////////////////////////////////////////////////////////////////////////

    AT91C_BASE_PMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8) | AT91C_CKGR_MOSCEN ));

    // Wait Main Oscillator stabilization

    while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));

 

    /////////////////////////////////////////////////////////////////////////////////////////////////////

    // Init PMC Step 2. 配置PLL输出时钟和USB时钟  18.432 * (72+1)/14 = 96,109MHz

    // Set PLL to 96MHz (96,109MHz) and UDP Clock to 48MHz

    // PLL Startup time depends on PLL RC filter: worst case is choosen

    // UDP Clock (48,058MHz) is compliant with the Universal Serial Bus Specification (+/- 0.25% for full speed)

    /////////////////////////////////////////////////////////////////////////////////////////////////////

    AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1 | AT91C_CKGR_OUT_0 | AT91C_CKGR_PLLCOUNT |

      (AT91C_CKGR_MUL & (72 << 16)) | (AT91C_CKGR_DIV & 14);

    // Wait for PLL stabilization

    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) );

    // Wait until the master clock is established for the case we already turn on the PLL

    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );

 

    /////////////////////////////////////////////////////////////////////////////////////////////////////

    // Init PMC Step 3. 配置MCK为PLL输出分频2,处理器时钟PCK等于MCK

    // Selection of Master Clock MCK (equal to Processor Clock PCK) equal to PLL/2 = 48MHz

    // The PMC_MCKR register must not be programmed in a single write operation (see. Product Errata Sheet)

    /////////////////////////////////////////////////////////////////////////////////////////////////////

/*
    AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;  // 分频2

    // Wait until the master clock is established

    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );

 

    AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;//选PLL为时钟

    // Wait until the master clock is established

    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );

 
*/
    /////////////////////////////////////////////////////////////////////////////////////////////////////

    //  Disable Watchdog (write once register)

    /////////////////////////////////////////////////////////////////////////////////////////////////////

    AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;

 

    ////////////////////////////////////////////////////////////////////////////////////////////////////

    //  Init AIC: assign corresponding handler for each interrupt source

    /////////////////////////////////////////////////////////////////////////////////////////////////////
/*
    AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler ;

    for (i = 1; i < 31; i++)

    {

        AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler ;

    }

    AT91C_BASE_AIC->AIC_SPU = (unsigned int) AT91F_Spurious_handler;
*/
  }
//-----------------------------------------------------------------------------
int main()
{
  unsigned int i=0;
// AT91F_LowLevelInit();
 Init_GPIO();  
 Init_UART0();
//US0_init();    
   while(1)
   {
    delay(0xffff);
     i=~GPIO_B->PIO_PDSR;
  if((i&Key1)==Key1)
   GPIO_B->PIO_CODR|=LED1;
  else
   GPIO_B->PIO_SODR|=LED1;
  if((i&Key2)==Key2)
   GPIO_B->PIO_CODR|=LED2;
  else
   GPIO_B->PIO_SODR|=LED2;
  if((i&Key3)==Key3)
   GPIO_B->PIO_CODR|=LED3;
  else
   GPIO_B->PIO_SODR|=LED3;
  if((i&Key4)==Key4)
   GPIO_B->PIO_CODR|=LED4;
  else
   GPIO_B->PIO_SODR|=LED4;
//  i=GPIO_B->PIO_ODSR;
  SendChar(0X55);
  SendChar(0Xbb);
//  LED_Display();
 // while(!(*AT91C_US0_CSR&0x02));
 // *AT91C_US0_THR=0xaa;
  delay(0xffffF);
   }
   return 0;
}
//-------------------------------

原创粉丝点击