这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » Renesas » anananjjj的试用进程贴(调试10:uCOS-II移植实现距)

共27条 3/3 1 2 3 跳转至
工程师
2012-08-27 20:37:37     打赏
21楼

调试5:温度测定,AD数据采集
今天把AD采样程序给调试成功了。
1、图片


2、视频:

3、关键代码:
系统初始化:
void systeminit(void)
{
 PIOR = 0x00U;
 CG_ReadResetSource();
 PORT_Init();
 CLOCK_Init();
 NOKIA_5110_init();//这里用到了显示屏
 AD_Init();//AD采样的初始化
 IT_Init();
 CRC0CTL = 0x00U;
 IAWCTL = 0x00U;
}

主程序:

void  main(void)
{
 /* Start user code. Do not edit comment generated here */

        /* Peripheral start function calls */
        IT_Start();                   /* Start Interval Timer */
        ADC_Init_ResultBuffer();
        AD_ComparatorOn();            /* Enable ADC voltage comparator (ADCE = on) */
        UINT i;
        for (i=0; i < 100; i++)
         {
            NOP();
         }
           
        AD_Start();                   /* Start ADC (ADCS = 0n) */
//显示屏的初始化显示
        NOKIA_5110_write_chinese_string(0,0,12,7,0,0);//瑞萨开发板试用
        NOKIA_5110_write_chinese_string(0,2,12,3,7,0);//电压
        NOKIA_5110_write_chinese_string(0,4,12,3,10,0);//温度
        NOKIA_5110_write_chinese_string(73,4,12,1,13,0);//度
        lcdUpdateChar(2,7,'.');
        lcdUpdateChar(2,13,'V');
        lcdUpdateChar(4,8,'.');
        /* Endless control loop */
 while (1U)
 {
           
            /* ADC Conversions (External Voltage, Temperature and Reference Voltage)  */
            while (!ADIF) {}                                 // Wait for first AD conversion completion
            ADIF = 0;
            temp_read = (USHORT)(ADCR >> 6U);                // Ignore first ADC reading
          
            ADC_Calculation_Ref();                           // Calculate internal reference voltage value
            AD_SelectADChannel(ADCHANNEL2);                  // Switch to external voltage (Channel 2)
            for (i=0; i < 100; i++)
            {
                NOP();
            }
           
            ADC_Calculation_ExtVoltage();                    // Calculate external voltage value
            AD_SelectADChannel(ADTEMPERSENSOR0);             // Switch to temperature sensor channel
            for (i=0; i < 500; i++)
            {
                NOP();
            }
           
            ADC_Calculation_Temp();                          // Calculate temperature value
            AD_SelectADChannel(ADTEMPERSENSOR1);             // Switch to internal reference voltage channel
            for (i=0; i < 100; i++)
            {
                NOP();
            }
           
            LCD_Accel_Value2(2,6,(int)(g_voltage*1000));          //转换电压值
            LCD_Accel_Value(4,6,(int)(g_temperature*100));      //转换温度

 }

其中:
void AD_Init(void)
{
 ADCEN = 1U; /* supply AD clock */
 ADM0 = _00_AD_ADM0_INITIALVALUE; /* disable AD conversion and clear ADM0 register */
 ADMK = 1U; /* disable INTAD interrupt */
 ADIF = 0U; /* clear INTAD interrupt flag */
 /* Set INTAD low priority */
 ADPR1 = 1U;
 ADPR0 = 1U;
 ADPC = _04_AD_ADPC_3ANALOG;
 /* Set ANI0 - ANI2 pin as analog input */
 PM2 |= 0x07U;
 ADM0 = _20_AD_CONVERSION_CLOCK_6 | _00_AD_TIME_MODE_STANDARD_1 | _00_AD_OPERMODE_SELECT;
 ADM1 = _00_AD_TRIGGER_SOFTWARE | _00_AD_CONVMODE_CONSELECT;
 ADM2 = _00_AD_POSITIVE_VDD | _00_AD_NEGATIVE_VSS | _00_AD_AREA_MODE_1 | _00_AD_RESOLUTION_10BIT;
 ADUL = _FF_AD_ADUL_VALUE;
 ADLL = _00_AD_ADLL_VALUE;
 ADS = _81_AD_INPUT_TEMPERSENSOR_1;
}

void AD_Start(void)
{
 ADIF = 0U; /* clear INTAD interrupt flag */
 ADMK = 0U; /* enable INTAD interrupt */
 ADCS = 1U; /* enable AD conversion */
}


void ADC_Init_ResultBuffer(void)
{
        UCHAR i;
        for (i = 0 ; i < 10 ; i++)
        {
          ADC_result[i] = 0;                  // Clear ADC result buffer
        }
}

void ADC_Calculation_ExtVoltage(void)
{
  if (samples >= 3)
      {
        samples = 0;
      }
  AD_Read(&ADC_result[samples]);                                   // Store the conversion result in the buffer
  temp = (float) 1.44 / g_ref_hexvalue;
  g_voltage = (float) ((ADC_result[samples] & 0xFFFC) * temp);     // Calculate the external voltage value
  samples++;
 
}

void ADC_Calculation_Temp(void)
{
  if (samples >= 3)
      {
        samples = 0;
      }
  AD_Read(&ADC_result[samples]);                                                           // Store the conversion result in the buffer
  temp = (float) 1.44 / g_ref_hexvalue;
  g_temperature = (float) (25 - ((((ADC_result[samples] * temp) - 1) * 1000) / 3.6));      // Calculate the temperature value in 癈
  samples++;
 
}


void ADC_Calculation_Ref(void)
{
  if (samples >= 3)
      {
        samples = 0;
      }
  AD_Read(&ADC_result[samples]);                            // Store the conversion result in the buffer
  g_ref_hexvalue = ADC_result[samples];
  samples++;
 
}


读取数据
void AD_Read(USHORT *buffer)
{
 *buffer = (USHORT)(ADCR >> 6U);
}

//选择通道
MD_STATUS AD_SelectADChannel(enum ADChannel channel)
{
 MD_STATUS status = MD_OK;

 if (((channel > ADCHANNEL7) && (channel < ADCHANNEL16)) || ((channel > ADCHANNEL19) && (channel < ADTEMPERSENSOR0)) || (channel > ADTEMPERSENSOR1))
 {
  status = MD_ARGERROR;
 }
 else
 {
  ADS = (UCHAR)channel;
 }

 return (status);
}


工程师
2012-09-01 22:07:22     打赏
22楼

调试6:RL78 AD采样麦克风放大电压信号:
1、放大电路:


2、实物图:


3、相关资料:
电压放大芯片:
LM358.pdf
麦克风:
MSMAS42Z.pdf
4、关键程序:
在调试5的基础上:
ADPC = _04_AD_ADPC_3ANALOG;
 /* Set ANI0 - ANI3 pin as analog input */
        PM2 |= 0x0FU;
AD输入选择通道3.

采样程序:
void ADC_Calculation_Mic(void)
{
  if (samples >= 3)
      {
        samples = 0;
      }
  AD_Read(&ADC1_result[samples]);                            // Store the conversion result in the buffer
  g_mic = ADC1_result[samples];
  samples++;
 
}

主程序中的主循环中执行:

 AD_SelectADChannel(ADCHANNEL3);                  // Switch to external voltage (Channel 2)
            for (i=0; i < 100; i++)
            {
                NOP();
            }
           
            ADC_Calculation_Mic();         
           
            if(g_mic<450)
            {
              LCD_write_english_string(0,0,"||            ");
            }
           
             if(g_mic>450&&g_mic<500)
            {
              LCD_write_english_string(0,0,"||||||        ");
            }
           
             if(g_mic>500&&g_mic<550)
            {
              LCD_write_english_string(0,0,"||||||||||    ");
            }
            if(g_mic>550)
            {
              LCD_write_english_string(0,0,"||||||||||||||");
            }
           
            LCD_Accel_Value1(3,1,g_mic);

5、测试视频:(背景音是我用嘴吹麦克风的声音,可以看到数据和图形都在变化!)


工程师
2012-09-10 20:59:51     打赏
23楼

调试7:RL78与MSP-EXP430FR5739开发板无线通讯(传递三轴加速度值,超声波距离和温度值)
原来用430做过这个实验,所以算是一种移植吧!
1、功能:把MSP-EXP430FR5739开发板上的三轴加速度值和超声波模块采集的距离值以及热敏电阻的值通过无线模块Nrf24l01传送给RL78然后通过其LCD显示出数据的变化。
LCD的布局:

关于“MSP-EXP430FR5739开发板”相信大家不会陌生了!我这就把他的手册分享一下吧!
MSP-EXP430FR5739 usersguide.pdf
至于Nrf24l01的操作其实比较简单,根据时序编出驱动程序后就可以移植到任何一款单片机上!
NRF24l01.pdf
2、关键程序:

//---------------------NRF24L01引脚定义------------------------
        
#define CE_ON()        P0_bit.no5=HIGH; 
#define CE_OFF()      P0_bit.no5=LOW;

#define CSN_ON()        P0_bit.no6=HIGH;  
#define CSN_OFF()      P0_bit.no6=LOW;

#define MOSI_ON()        P4_bit.no1=HIGH; 
#define MOSI_OFF()      P4_bit.no1=LOW;

#define SCK_ON()        P4_bit.no2=HIGH;  
#define SCK_OFF()      P4_bit.no2=LOW;

#define MISO_IN            P14_bit.no6==HIGH

#define IRQ_IN            P14_bit.no7==HIGH

具体驱动:
uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
 uchar status,byte_ctr;
 
 CSN_OFF();                  //使用SPI               
 status = SPI_RW(reg);     //写地址
 for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) //写数据
  SPI_RW(*pBuf++);
 CSN_ON();                 // 设置高
 return(status);          //
}


uchar SPI_RW_Reg(BYTE reg, BYTE value)
{
 uchar status;
 
 CSN_OFF();                   // CSN low, init SPI transaction
 status = SPI_RW(reg);      // 选择寄存器
 SPI_RW(value);             // 写入数据
 CSN_ON();                   // CSN high again
 
 return(status);            // return nRF24L01 status byte
}

uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
 uchar status,byte_ctr;
 
 CSN_OFF();                      // SPI使能
 status = SPI_RW(reg);         // 选择寄存器
 
 for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
  pBuf[byte_ctr] = SPI_RW(0);    // 读取寄存器
 
 CSN_ON();                          
 
 return(status);                    // return nRF24L01 status byte
}

//-------------------IO口初始化函数-------------------------------
void IO_Init(void)
{
       
       
  CE_OFF();    // 待机模式
  CSN_ON();   // SPI禁止
  SCK_OFF();   // SPI时钟信号低
}

//----------------------------SPI单字节写入函数---------------------------
uchar SPI_RW(unsigned char byte)
{
uchar bit_ctr;
        SCK_OFF();
       
    for(bit_ctr=0;bit_ctr<8;bit_ctr++)               // output 8-bit
    {     
               
         
               
                if(byte & 0x80)
                {
     MOSI_ON();
                }
                else
                {
                MOSI_OFF();                   // output 'byte', MSB to MOSI
                }
               
     byte = (byte << 1);                     // shift next bit into MSB..
     SCK_ON();                        // Set clk high..
                if(MISO_IN)
                {
     byte |= BIT0;                 // capture current MISO bit
                }
                else
                { 
                byte &=~BIT0;
                }
     SCK_OFF();                        // set  clk low
    }
        MOSI_OFF();                              //PULL DOWN THE MOSI
    return(byte);                              // return read byte
}

BYTE SPI_Read(BYTE reg)
{
 BYTE reg_val;
 
 CSN_OFF();                // SPI片选使能
 SPI_RW(reg);            // 选择寄存器
 reg_val = SPI_RW(0);    // 读出寄存器的值
 CSN_ON();                // CSN高终止SPI通信
 
 return(reg_val);        // return register value
}

unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
    unsigned char revale=0;

 //SetRX_Mode();

 sta=SPI_Read(STATUS); // 读状态寄存器
 if(sta&0x40)  // 如果是接收数据中断
 {
     CE_OFF();     //不是能发送或接收
     SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);//读数据
     revale =1;//表示接收到数据
 }
 SPI_RW_Reg(WRITE_REG+STATUS,sta);// clear RX_DR or TX_DS or MAX_RT interrupt flag
 
 return revale;
}

void nRF24L01_TxPacket(unsigned char * tx_buf)
{
 CE_OFF();          //不是能发送或接收,   为待机状态
 
 SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    //写发送地址
 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //设置P0接收地址,默认为5字节
 SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);  //写Tx有效数据
 
 SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // 数据通道0自动应答允许
 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // 接收数据通道0允许
 SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); //应答500us,最大自动重发10次
 SPI_RW_Reg(WRITE_REG + RF_CH, 20);        //设置工作通道频率
 SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // 0dB,2M
 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     // 使能中断,16位CRC,发射模式,PWR_UP
 CE_ON();
 Delay(100);  //>10us
 //sta=SPI_Read(STATUS); // read register STATUS's value
 //SPI_RW_Reg(WRITE_REG+STATUS,SPI_Read(READ_REG+STATUS)); // clear interrupt flag(TX_DS)
 
}

void SetRx_Mode(void)
{
 CE_OFF();   //禁止发送或接收
  SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 数据通道0接收地址 
 SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // 数据通道0自动应答允许
 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // 接收数据通道0允许
 SPI_RW_Reg(WRITE_REG + RF_CH, 20);        // 设置工作通道频率
 SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //数据通道0有效数据宽度
 SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   //0dB,2M
 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     //使能所有中断,PWR_UP,接收模式 
 CE_ON();        //启动发送或接收
 Delay(6000);

}


至于具体数据的处理,那都是430里的程序,我这里主要讲的是RL78无线接收的程序:
主程序中:
编辑LCD界面:
 lcdUpdateLine(0,"Acc(g): Angle:");
  lcdUpdate("X:         .","Y:         .");
  lcdUpdateLine(3,"Z:         .");
  lcdUpdateLine(4,"a:      T(C):");
  lcdUpdateLine(5,"s:      cm|");
 
  lcdUpdateChar(1, 4, 46);
  lcdUpdateChar(2, 4, 46);
  lcdUpdateChar(3, 4, 46);
  lcdUpdateChar(4, 4, 46);
 
  lcdUpdateChar(0, 7, 124);
  lcdUpdateChar(1, 7, 124);
  lcdUpdateChar(2, 7, 124);
  lcdUpdateChar(3, 7, 124);
  lcdUpdateChar(4, 7, 124);
循环中判断无线模块是否工作:
while (1)
  {

         if(nRF24L01_RxPacket(RxBuf))   
  {
其中为数据的处理:
Judge(1,2,RxBuf[0]);
                   Judge(2,2,RxBuf[2]);
                   Judge(3,2,RxBuf[4]);
                   LCD_Accel_Value( 1, 3, RxBuf[1]);
                   LCD_Accel_Value( 2, 3, RxBuf[3]);
                   LCD_Accel_Value( 3, 3, RxBuf[5]);
     LCD_Accel_Value( 4, 3, RxBuf[6]);
                   LCD_Accel_Value1( 5, 12,RxBuf[7]);
                  S=RxBuf[9]*256+RxBuf[8];//超声波的数据处理              
                  n1=S/10000;
                  n2=(S%10000)/1000;
                  n3=(S%1000)/100;
                  n4=(S%100)/10;   
                  n5=S%10;
                  lcdUpdateChar(5, 2,n1+48);
                  lcdUpdateChar(5, 3,n2+48);
                  lcdUpdateChar(5, 4,n3+48);
                  lcdUpdateChar(5, 5,46);
                  lcdUpdateChar(5, 6,n4+48);
                  lcdUpdateChar(5, 7,n5+48);
                                          //倾角的计算
                  //X
                  if(RxBuf[0]==45)
                   {
                      Xg=-((float)RxBuf[1]/100);
                   }
                  else if(RxBuf[0]==43)
                   {
                     Xg=((float)RxBuf[1]/100);
                   }
                  if(Xg<-1)
                  {
                    Xg=-1;
                  }
                  else if(Xg>1)
                  {
                    Xg=1;
                  }
                  Xg=100*(180*asin(Xg)/3.14);
                  if(Xg<0)
                  {
                    Xg=fabs(Xg);
                    lcdUpdateChar(1, 8,45);
                    LCD_Accel_Value2(1,9,(int)Xg);
                  }
                  else
                  {
                    lcdUpdateChar(1, 8,43);
                    LCD_Accel_Value2(1,9,(int)Xg);
                  }
                  //Y
                  if(RxBuf[2]==45)
                   {
                      Yg=-((float)RxBuf[3]/100);
                   }
                  else if(RxBuf[2]==43)
                   {
                     Yg=((float)RxBuf[3]/100);
                   }
                  if(Yg<-1)
                  {
                    Yg=-1;
                  }
                  else if(Yg>1)
                  {
                    Yg=1;
                  }
                  Yg=100*(180*asin(Yg)/3.14);
                  if(Yg<0)
                  {
                    Yg=fabs(Yg);
                    lcdUpdateChar(2, 8,45);
                    LCD_Accel_Value2(2,9,(int)Yg);
                  }
                  else
                  {
                    lcdUpdateChar(2, 8,43);
                    LCD_Accel_Value2(2,9,(int)Yg);
                  }
                //Z
                if(RxBuf[4]==45)
                   {
                      Zg=-((float)RxBuf[5]/100);
                   }
                  else if(RxBuf[4]==43)
                   {
                     Zg=((float)RxBuf[5]/100);
                   }
                if(Zg<-1)
                  {
                    Zg=-1;
                  }
                  else if(Zg>1)
                  {
                    Zg=1;
                  }
                  Zg=100*(180*asin(Zg)/3.14);
                if(Zg<0)
                  {
                    Zg=fabs(Zg);
                    lcdUpdateChar(3, 8,45);
                    LCD_Accel_Value2(3,9, (int)Zg);
                  }
                  else
                  {
                    lcdUpdateChar(3, 8,43);
                    LCD_Accel_Value2(3,9,(int)Zg);
                  }
                }

这里是将此模块设置为接收模式:
  SPI_RW(FLUSH_RX);  //清空接收缓冲
  Delay(60000);
  SetRx_Mode(); 
}

3、图片:






4、调试视频(拉动超声波模块,转动开发板XYZ数据变化,按住热敏电阻温度值变化)


工程师
2012-09-14 16:09:50     打赏
24楼

调试8:RS232串口通信(通过串口助手实现字符的收发,同时收到的内容显示在LCD上,并且解决了LCD同时显示中英文的问题)

1、利用串口2:


使用了U转串的转接板,将串口接出!这样实现了调试和串口通讯两不误!
2、图片:


图中带白色线的为U转串!



发送和接收的情况.

3、关键程序:
主程序中初始化:

UART2_Init();

 SAU1_Init();

 UART2_Start();

void UART2_Init(void)
{
 ST1 |= _0002_SAU_CH1_STOP_TRG_ON | _0001_SAU_CH0_STOP_TRG_ON; /* disable UART2 receive and transmit */
 STMK2 = 1U; /* disable INTST2 interrupt */
 STIF2 = 0U; /* clear INTST2 interrupt flag */
 SRMK2 = 1U; /* disable INTSR2 interrupt */
 SRIF2 = 0U; /* clear INTSR2 interrupt flag */
 SREMK2 = 1U; /* disable INTSRE2 interrupt */
 SREIF2 = 0U; /* clear INTSRE2 interrupt flag */
 /* Set INTST2 low priority */
 STPR12 = 1U;
 STPR02 = 1U;
 /* Set INTSR2 low priority */
 SRPR12 = 1U;
 SRPR02 = 1U;
 /* Set INTSRE2 low priority */
 SREPR12 = 1U;
 SREPR02 = 1U;
 SMR10 = _0020_SAU_SMRMN_INITIALVALUE | _0000_SAU_CLOCK_SELECT_CK00 | _0000_SAU_TRIGGER_SOFTWARE | _0002_SAU_MODE_UART | _0000_SAU_TRANSFER_END;
 SCR10 = _8000_SAU_TRANSMISSION | _0000_SAU_INTSRE_MASK | _0000_SAU_PARITY_NONE | _0080_SAU_LSB | _0010_SAU_STOP_1 | _0007_SAU_LENGTH_8;
 SDR10 = _CE00_UART2_TRANSMIT_DIVISOR;
 NFEN0 |= _10_SAU_RXD2_FILTER_ON;
 SIR11 = _0004_SAU_SIRMN_FECTMN | _0002_SAU_SIRMN_PECTMN | _0001_SAU_SIRMN_OVCTMN; /* clear error flag */
 SMR11 = _0020_SAU_SMRMN_INITIALVALUE | _0000_SAU_CLOCK_SELECT_CK00 | _0100_SAU_TRIGGER_RXD | _0000_SAU_EDGE_FALL | _0002_SAU_MODE_UART | _0000_SAU_TRANSFER_END;
 SCR11 = _4000_SAU_RECEPTION | _0400_SAU_INTSRE_ENABLE | _0000_SAU_PARITY_NONE | _0080_SAU_LSB | _0010_SAU_STOP_1 | _0007_SAU_LENGTH_8;
 SDR11 = _CE00_UART2_RECEIVE_DIVISOR;
 SO1 |= _0001_SAU_CH0_DATA_OUTPUT_1;
 SOL1 |= _0000_SAU_CHANNEL0_NORMAL; /* output level normal */
 SOE1 |= _0001_SAU_CH0_OUTPUT_ENABLE; /* enable UART2 output */
 /* Set RxD2 pin */
 PM1 |= 0x10U;
 /* Set TxD2 pin */
 P1 |= 0x08U;
 PM1 &= 0xF7U;
}
/*
**-----------------------------------------------------------------------------
**
**  Abstract:
** This function starts the UART2 module operation.
**
**  Parameters:
** None
**
**  Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void UART2_Start(void)
{
 STIF2 = 0U; /* clear INTST2 interrupt flag */
 STMK2 = 0U; /* enable INTST2 interrupt */
 SRIF2 = 0U; /* clear INTSR2 interrupt flag */
 SRMK2 = 0U; /* enable INTSR2 interrupt */
 SREIF2 = 0U; /* clear INTSRE2 interrupt flag */
 SREMK2 = 0U; /* enable INTSRE2 interrupt */
 SO1 |= _0001_SAU_CH0_DATA_OUTPUT_1; /* output level normal */
 SOE1 |= _0001_SAU_CH0_OUTPUT_ENABLE; /* enable UART2 output */
 SS1 |= _0002_SAU_CH1_START_TRG_ON | _0001_SAU_CH0_START_TRG_ON; /* enable UART2 receive and transmit */
}

在中断程序中:

#pragma vector = INTSR2_vect
__interrupt void MD_INTSR2(void)
{
 UCHAR rx_data;

 rx_data = RXD2;
 if (gUart2RxLen > gUart2RxCnt)
 {
  *gpUart2RxAddress = rx_data;
  gpUart2RxAddress++;
  gUart2RxCnt++;
  if (gUart2RxLen == gUart2RxCnt)
  {
   UART2_ReceiveEndCallback();
  }
 }
 else
 {
  UART2_SoftOverRunCallback(rx_data);
 }
}


#pragma vector = INTST2_vect
__interrupt void MD_INTST2(void)
{
 if (gUart2TxCnt > 0U)
 {
  TXD2 = *gpUart2TxAddress;
  gpUart2TxAddress++;
  gUart2TxCnt--;
 }
 else
 {
  UART2_SendEndCallback();
 }
}

其中:
MD_STATUS UART2_ReceiveData(UCHAR *rxbuf, USHORT rxnum)
{
 MD_STATUS status = MD_OK;

 if (rxnum < 1U)
 {
  status = MD_ARGERROR;
 }
 else
 {
  gUart2RxCnt = 0U;
  gUart2RxLen = rxnum;
  gpUart2RxAddress = rxbuf;
 }

 return (status);
}

MD_STATUS UART2_SendData(UCHAR* txbuf, USHORT txnum)
{
 MD_STATUS status = MD_OK;

 if (txnum < 1U)
 {
  status = MD_ARGERROR;
 }
 else
 {
  gpUart2TxAddress = txbuf;
  gUart2TxCnt = txnum;
  STMK2 = 1U; /* disable INTST2 interrupt */
  TXD2 = *gpUart2TxAddress;
  gpUart2TxAddress++;
  gUart2TxCnt--;
  STMK2 = 0U; /* enable INTST2 interrupt */
 }

 return (status);
}

在主程序中执行一次:
UART2_ReceiveData(RxBuf,14);之后
会进入接收中断函数:
接收中断函数执行完后进入:
接收回调函数:
void UART2_ReceiveEndCallback(void)
{
  UART2_SendData(RxBuf,14);
  //Nokia_Clear_Line(5);
  Nokia_Clear_Line(4);
  Nokia_Clear_Line(5);
  for(int j=0;j<14;j++)
  {
    if((j%2==0)&&(RxBuf[j]&0x80))
    {
      c=j*6;//间距12
      for(int k=0;k<28;k++)
      {
        if((RxBuf[j]==Hanzi[k])&&(RxBuf[j+1]==Hanzi[k+1]))
        {
      NOKIA_5110_write_chinese_string(c,4,12,1,Wezhi[k/2],0);
        }
      }
      j++;
    }

    else
    {
      lcdUpdateChar(4,j,RxBuf[j]);
    }
  }
  //lcdUpdateLine(5,RxBuf);
 
 /* Start user code. Do not edit comment generated here */
 /* End user code. Do not edit comment generated here */
}
这里执行了串口发送程序和LCD判断中英文并显示的程序,其中:

unsigned char Hanzi[28]={"瑞萨开发板串口测试:我爱你!"};
unsigned char Wezhi[14]={0,1,2,3,4,5,6,7,8,9,10,11,12,13};//瑞萨开发板串口测试:我爱你!
unsigned char c=0;
中文使用的是查询方法得到的。

而在发送中断函数结束后进入回调函数:
void UART2_SendEndCallback(void)
{
 
  for(int i=0;i<16;i++)
  {
    RxBuf[i]=0;
  }
  UART2_ReceiveData(RxBuf,14);
 /* Start user code. Do not edit comment generated here */
 /* End user code. Do not edit comment generated here */
}

清除接受Buffer,同时再次启动接收!!

4、视频:


工程师
2012-09-17 20:30:31     打赏
25楼

调试9:定时器应用——超声波模块测距

1、超声波模块原理介绍:




2、设置定时器:
利用Applilet3来设置定时器:


得到代码:
void TAU0_Init(void)
{
 TAU0EN = 1U;  /* supplies input clock */
 
        TPS0 = _0000_TAU_CKM0_FCLK_0 | _0000_TAU_CKM1_FCLK_0 | _0000_TAU_CKM2_FCLK_1 | _0000_TAU_CKM3_FCLK_8;
 /* Stop all channels */
 
        TT0 = _0001_TAU_CH0_STOP_TRG_ON | _0002_TAU_CH1_STOP_TRG_ON | _0004_TAU_CH2_STOP_TRG_ON | _0008_TAU_CH3_STOP_TRG_ON | _0010_TAU_CH4_STOP_TRG_ON | _0020_TAU_CH5_STOP_TRG_ON | _0040_TAU_CH6_STOP_TRG_ON | _0080_TAU_CH7_STOP_TRG_ON | _0200_TAU_CH1_H8_STOP_TRG_ON | _0800_TAU_CH3_H8_STOP_TRG_ON;
 /* Mask channel 0 interrupt */
 
        TMMK00 = 1U; /* disable INTTM00 interrupt */
 
        TMIF00 = 0U; /* clear INTTM00 interrupt flag */
 
        /* Mask channel 1 interrupt */
 
        TMMK01 = 1U; /* disable INTTM01 interrupt */
 
        TMIF01 = 0U; /* clear INTTM01 interrupt flag */
 
        /* Mask channel 1 higher 8 bits interrupt */
 
        TMMK01H = 1U; /* disable INTTM01H interrupt */
 
        TMIF01H = 0U; /* clear INTTM01H interrupt flag */
 
        /* Mask channel 2 interrupt */
 
        TMMK02 = 1U; 
        /* disable INTTM02 interrupt */
 
        TMIF02 = 0U; /* clear INTTM02 interrupt flag */
 
        /* Mask channel 3 interrupt */
 
        TMMK03 = 1U; /* disable INTTM03 interrupt */
 
        TMIF03 = 0U; /* clear INTTM03 interrupt flag */
 
        /* Mask channel 3 higher 8 bits interrupt */
 
        TMMK03H = 1U; /* disable INTTM03H interrupt */
 
        TMIF03H = 0U; /* clear INTTM03H interrupt flag */
 
        /* Mask channel 4 interrupt */
 
        TMMK04 = 1U; 
        /* disable INTTM04 interrupt */
 
        TMIF04 = 0U; /* clear INTTM04 interrupt flag */
 
        /* Mask channel 5 interrupt */
 
        TMMK05 = 1U; /* disable INTTM05 interrupt */
 
        TMIF05 = 0U; /* clear INTTM05 interrupt flag */
 
        /* Mask channel 6 interrupt */
 
        TMMK06 = 1U; /* disable INTTM06 interrupt */
 
        TMIF06 = 0U; /* clear INTTM06 interrupt flag */
 
        /* Mask channel 7 interrupt */
 
        TMMK07 = 1U; /* disable INTTM07 interrupt */
 
        TMIF07 = 0U; /* clear INTTM07 interrupt flag */

       
 /* Set INTTM00 high priority */
 TMPR100 = 0U;
 TMPR000 = 0U; 
        /* Channel 0 used as interval timer */
 
        TMR00 = _0000_TAU_CLOCK_SELECT_CKM0 | _0000_TAU_CLOCK_MODE_CKS | _0000_TAU_COMBINATION_SLAVE | _0000_TAU_TRIGGER_SOFTWARE | _0000_TAU_MODE_INTERVAL_TIMER | _0001_TAU_START_INT_USED;
 TDR00 = _001F_TAU_TDR00_VALUE;
 
        TO0 &= ~_0001_TAU_CH0_OUTPUT_VALUE_1;
 
        TOE0 &= ~_0001_TAU_CH0_OUTPUT_ENABLE;
 
}
/*
**-----------------------------------------------------------------------------
**
**  Abstract:
** This function starts TAU0 channel 0 counter.
**
**  Parameters:
** None
**
**  Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void TAU0_Channel0_Start(void)
{
 TMIF00 = 0U; /* clear INTTM00 interrupt flag */
 TMMK00 = 0U; /* enable INTTM00 interrupt */
 TS0 |= _0001_TAU_CH0_START_TRG_ON;
}
/*
**-----------------------------------------------------------------------------
**
**  Abstract:
** This function stops TAU0 channel 0 counter.
**
**  Parameters:
** None
**
**  Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void TAU0_Channel0_Stop(void)
{
 TT0 |= _0001_TAU_CH0_STOP_TRG_ON;
 /* Mask channel 0 interrupt */
 TMMK00 = 1U; /* disable INTTM00 interrupt */
 TMIF00 = 0U; /* clear INTTM00 interrupt flag */
}

3、关键程序:

主程序中只需启动定时器:TAU0_Channel0_Start();

主循环中:
   S=change_distence();
   LCD_Accel_Value2(4,0,S);

其中:
void delay1(void)   

 uchar i;
 for(i=11;i>0;i--);
}

void Get_distance(void)
{
  unsigned long int i=162400;       //3.5m测距所需的时间
  Trig_1;           //触发
  delay1();
  Trig_0; //停止触发
 //检测输入信号
 while(!(EchoIN==1)&&i>0)
 {
   i--;
 }
 if (i>0)
  {
  tick_1us=0;
  while(EchoIN==1);
  temp1=tick_1us;
  }
 
}
unsigned int change_distence()

  unsigned long int i;
   Get_distance();
   k=temp1/58.00;
   i=(uint)(k*100);
  return i;
 }

而关键的 tick_1us
是在定时中断:
#pragma vector = INTTM00_vect
__interrupt void MD_INTTM00(void)
{
 
 /* Start user code. Do not edit comment generated here */
       TM00_flag = TRUE;
       tick_1us++;
 /* End user code. Do not edit comment generated here */
}
得到的!

4、图片:




5、视频:


工程师
2012-09-23 16:08:46     打赏
26楼

调试10:uCOS-II移植实现

1、在操作系统中建立了三个任务:

static  OS_STK  App_TaskStartStk[APP_CFG_TASK_START_STK_SIZE];

#define TASK_LED1_STACK_SIZE (128)
static OS_STK Task_LED1_Stack[TASK_LED1_STACK_SIZE];
void Task_LED1( void *Id ) ;
#define Task_LED1_PRIO       6

#define TASK_Beep_STACK_SIZE (128)
static OS_STK  Task_Beep_Stack[TASK_Beep_STACK_SIZE];
void Task_Beep( void *Id ) ;
#define Task_Beep_PRIO       5

#define TASK_LED_STACK_SIZE (128)
static OS_STK Task_LED2_Stack[TASK_LED_STACK_SIZE];
void Task_LED2( void *Id ) ;
#define  Task_LED2_PRIO       10
//以下为任务的具体内容
static  void  App_TaskCreate (void)
{
 
  OSTaskCreate( Task_LED1, (void *)0, (OS_STK *)&Task_LED1_Stack[TASK_LED1_STACK_SIZE-1], Task_LED1_PRIO ) ;
  OSTaskCreate( Task_LED2, (void *)0, (OS_STK *)&Task_LED2_Stack[TASK_LED_STACK_SIZE-1], Task_LED2_PRIO ) ;
  OSTaskCreate( Task_Beep, (void *)0, (OS_STK *)&Task_Beep_Stack[TASK_Beep_STACK_SIZE-1], Task_Beep_PRIO ) ;
}

void Task_LED1( void *Id )
{
 for( ; ; ) 
 { 
                BSP_LED_Toggle(1);
                LCD_clear();
                LCD_write_english_string(0,0,"LED1 Change!");
  OSTimeDly(500);
 }
}

void Task_Beep( void *Id )
{
 for( ; ; ) 
 {
                BSP_Beep_Toggle();
                LCD_clear();
                LCD_write_english_string(0,2,"Beep ring!");
  OSTimeDly(100); 
 }
}

void Task_LED2( void *Id )
{

 for(;;)
 {
          BSP_LED_Toggle(2);
          LCD_clear();
          LCD_write_english_string(0,4,"LED1 Change!");
   OSTimeDly(1000);//1s
 }
}

2、由于移植自Micrium,所以改动不大只是移植,然后编写了几个任务!

3、图片视频:


测试视频:


工程师
2012-09-23 21:31:58     打赏
27楼
这几天正在纠结到底买不买那个FPGA呢!一是我这个月钱紧(学生当伤不起),二是怕没时间!不知道过段时间买不行啊!

共27条 3/3 1 2 3 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]