查看: 4097|回复: 6

[原创] 【IRD-LPC1768-DEV】初步测试计划完成

[复制链接]
  • TA的每日心情
    开心
    2024-4-5 11:15
  • 签到天数: 1061 天

    连续签到: 1 天

    [LV.10]以坛为家III

    29

    主题

    1517

    帖子

    31

    金牌会员

    Rank: 6Rank: 6

    积分
    4979
    最后登录
    2024-5-31
    发表于 2019-3-7 18:38:11 | 显示全部楼层 |阅读模式
    本帖最后由 story_xjj 于 2019-3-17 17:30 编辑

    测试报告1

    根据测试要求:
    编写上位机软件,支持usb或者网络转can转232。支持LCD显示配置参数以及通信数据,按键进行配置can工具。
    1、初步计划:
    上位机先采用串口,通过串口配置参数,下发接收LPC1768上报数据。
    实现usb转can转232功能。LPC1768实现CDC功能,接收上位机下发数据,上报接收的can和232数据。
    LCD显示参数,可以直接按键设置参数。
    2、进阶计划
    上位机支持网络接口,通过网络转can转232数据。
    3、终极计划:
    - 实现一个多功能调试工具辅助开发LPC产品。
    -USB转CAN
    - 移植嵌入式操作系统,如ucos,FreeRTOS或最近比较火的RT-Thread等
    完成第一步初步计划测试及成果如下。
    1 基本总结
       根据计划的要求,我们因该采用串口,USBCDC串口和LCD几个方式完成LPC1768自身串口和2CAN口数据交换和展示功能。
    此过程我的测试包括如下几个部分:
    1)完成数据监控所制定的协议
    2)LPC1768上的程序及代码
    3)PC机上位软件
    目前完成的内容中不包括USBCDC方式对数据端口的监控功能,原因是USB接口初始化始终无法成功,而且看了以下本论坛的其他人遇到了相同问题,因此,初步测试计划中不包括USBCDC方式,仅采用LPC1768-DEV串口0作为监控端口,完成测试功能。
    LCD菜单部分未完成参数输入,只完成了参数和状态显示。原因是我的上位软件可以管理所有监控端口,不需要LCD的输入。

    2  初步测试成果展示2.1 协议制定
    协议分为上行和下行两条,以主从问答式为基础。
    下行(PC->DEV)
      
    帧格式
      
    同步帧
    0xFF,0xFF
    设备对象
    0x00——无效
      
    0x01——UART0
      
    0x02——UART1
      
    0x03——CAN0
      
    0x04——CAN1
    命令字
    0x00——无效
      
    0x01——设置通讯对象参数同时打开
      
    0x02——通讯对象控制
      
    0x10——发送数据
      
    0x11——读取数据
    数据长度
    指示数据内容的长度,最大长度200字节
    数据内容
    以数据对象所通讯的数据帧为单位,例如:串口以1个字节为单位。

    上行(DEV->PC)
      
    帧格式
      
    同步帧
    0xFF,0xFF
    设备对象
    0x01——UART0
      
    0x02——UART1
      
    0x03——CAN0
      
    0x04——CAN1
    数据长度
    指示数据内容的长度,最大长度200字节
    数据内容
    以数据对象所通讯的数据帧为单位,例如:串口以1个字节为单位。

    使用方法举例:
    1)   串口1参数:波特率=115200bps,数据位=8位,停止位=1位,奇偶校验=无
    0xFF,0xFF,0x02,0x01,0x07,0x00,0x01,0xC2,0x00,0x03,0x00,0x00
    2)   打开串口1
    0xFF, 0xFF,0x02, 0x02,0x01,0x01
    3)   关闭串口1
    0xFF, 0xFF, 0x02,0x02,0x01,0x00

    2.2 DEV程序开发说明
    DEV程序包括主监控串口UART0的驱动,串口UART1的驱动,CAN驱动,键盘和显示I2C驱动,以及菜单设计。
    l  主程序框架
    主程序负责系统初始化,解析PC和IRD-LPC1768-DEV之间的数据,并执行。
        l  UART驱动
    1) 引脚初始化
    1. static void UART1_Init_Pin(void)
    2. {
    3.         // Pin configuration for UART0
    4.         PINSEL_CFG_Type PinCfg;
    5.         /*
    6.          * Initialize UART0 pin connect
    7.          */
    8.         PinCfg.Funcnum = 1;
    9.         PinCfg.OpenDrain = 0;
    10.         PinCfg.Pinmode = 0;
    11.         PinCfg.Pinnum = 15;
    12.         PinCfg.Portnum = 0;
    13.         PINSEL_ConfigPin(&PinCfg);
    14.         PinCfg.Pinnum = 16;
    15.         PINSEL_ConfigPin(&PinCfg);
    16.         }
    复制代码
    通过底板原理图和核心板原理图的对比,我们可以确定UART1的引脚为P0.15和P0.16。
    UART1-PIN1.jpg

    2) 串口初始化
    1. /*********************************************************************//**
    2. * @brief                UART1 initinal
    3. * @param[in]        uint32_t   baud         
    4. *              UART_DATABIT_Type db  data bits
    5. *              UART_STOPBIT_Type sb  stop bits
    6. *              UART_PARITY_Type pt   parity
    7. * @return                 None
    8. **********************************************************************/
    9. void UART1_Init(void)
    10. {
    11.         // UART FIFO configuration Struct variable
    12.         UART_FIFO_CFG_Type UARTFIFOConfigStruct;

    13.         uint32_t idx, len;
    14.         __IO FlagStatus exitflag;
    15.         uint8_t buffer[10];

    16.         /* Initialize UART Configuration parameter structure to default state:
    17.          * Baudrate = 9600bps
    18.          * 8 data bit
    19.          * 1 Stop bit
    20.          * None parity
    21.          */
    22.         //        UART_ConfigStructInit(&UARTConfigStruct);
    23.         // Initialize UART0 peripheral with given to corresponding parameter
    24.         UART_Init((LPC_UART_TypeDef *)LPC_UART1, &UARTConfigStruct);


    25.         /* Initialize FIFOConfigStruct to default state:
    26.          *                                 - FIFO_DMAMode = DISABLE
    27.          *                                 - FIFO_Level = UART_FIFO_TRGLEV0
    28.          *                                 - FIFO_ResetRxBuf = ENABLE
    29.          *                                 - FIFO_ResetTxBuf = ENABLE
    30.          *                                 - FIFO_State = ENABLE
    31.          */
    32.         UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);

    33.         // Initialize FIFO for UART0 peripheral
    34.         UART_FIFOConfig((LPC_UART_TypeDef *)LPC_UART1, &UARTFIFOConfigStruct);


    35.     // Disable THRE interrupt
    36.     UART_IntConfig((LPC_UART_TypeDef *)LPC_UART1, UART_INTCFG_THRE, DISABLE);
    37.         // Enable UART Transmit
    38.         UART_TxCmd((LPC_UART_TypeDef *)LPC_UART1, ENABLE);

    39.     /* Enable UART Rx interrupt */
    40.         UART_IntConfig((LPC_UART_TypeDef *)LPC_UART1, UART_INTCFG_RBR, ENABLE);
    41.         /* Enable UART line status interrupt */
    42.         UART_IntConfig((LPC_UART_TypeDef *)LPC_UART1, UART_INTCFG_RLS, ENABLE);

    43.         // Reset ring buf head and tail idx
    44.         __BUF_RESET(rb.rx_head);
    45.         __BUF_RESET(rb.rx_tail);
    46.         __BUF_RESET(rb.tx_head);
    47.         __BUF_RESET(rb.tx_tail);

    48.     /* preemption = 1, sub-priority = 1 */
    49.     NVIC_SetPriority(UART1_IRQn, ((0x01<<3)|0x02));
    50.         /* Enable Interrupt for UART0 channel */
    51.     NVIC_EnableIRQ(UART1_IRQn);

    52.         DeviceOpen = 1;
    53. }
    复制代码
    采用查询发送,中断接收的方式,接收和发送都采用了消息队列的方式作为二级缓存管理。
    3) 参数设置接口
    1. //参数设置接口
    2. void UART1_SetParam(uint8_t *dat)
    3. {
    4.         memcpy(&UARTConfigStruct, dat, sizeof(UART_CFG_Type));
    5.         UART1_Init_Pin();
    6.         UART1_Init();
    7. }
    8. 通过上位软件设置串口参数,并使能。
    复制代码
    4) 状态查询
    返回UART1的当前状态,可以在LCD上看到状态的变化。

    5) 中断+消息队列管理
    1. /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
    2. /*********************************************************************//**
    3. * @brief                UART1 interrupt handler sub-routine
    4. * @param[in]        None
    5. * @return                 None
    6. **********************************************************************/
    7. void UART1_IRQHandler(void)
    8. {
    9.         uint32_t intsrc, tmp, tmp1;

    10.         /* Determine the interrupt source */
    11.         intsrc = UART_GetIntId((LPC_UART_TypeDef*)LPC_UART1);
    12.         tmp = intsrc & UART_IIR_INTID_MASK;

    13.         // Receive Line Status
    14.         if (tmp == UART_IIR_INTID_RLS){
    15.                 // Check line status
    16.                 tmp1 = UART_GetLineStatus((LPC_UART_TypeDef*)LPC_UART1);
    17.                 // Mask out the Receive Ready and Transmit Holding empty status
    18.                 tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \
    19.                                 | UART_LSR_BI | UART_LSR_RXFE);
    20.                 // If any error exist
    21.                 if (tmp1) {
    22. //                                UART_IntErr(tmp1);
    23.                 }
    24.         }

    25.         // Receive Data Available or Character time-out
    26.         if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)){
    27.                         if (!__BUF_IS_FULL(rb.rx_head,rb.rx_tail)){
    28.                 rb.rx[rb.rx_head] = UART_ReceiveByte((LPC_UART_TypeDef*)LPC_UART1);
    29.                                 __BUF_INCR(rb.rx_head);
    30.                         }
    31.         }
    32. }
    33. 采用中断+消息队列方式,可以保证串口数据不丢失。
    复制代码
    l  CAN驱动
    DEV上有两个CAN接口,CAN的驱动针对CAN1和CAN2是相同的,这里以CAN1接口为例。

    1) CAN引脚初始化
    1. static void CAN1_Init_Pin(void)
    2. {
    3.         PINSEL_CFG_Type PinCfg;        
    4.         /* Pin configuration
    5.          * CAN1: select P0.0 as RD1. P0.1 as TD1
    6.          * CAN2: select P2.7 as RD2, P2.8 as RD2
    7.          */
    8.         PinCfg.Funcnum = 1;
    9.         PinCfg.OpenDrain = 0;
    10.         PinCfg.Pinmode = 0;
    11.         PinCfg.Pinnum = 0;
    12.         PinCfg.Portnum = 0;
    13.         PINSEL_ConfigPin(&PinCfg);
    14.         PinCfg.Pinnum = 1;
    15.         PINSEL_ConfigPin(&PinCfg);
    16. }
    复制代码
    通过底板原理图和核心板原理图的对比,我们可以确定CAN1的引脚为P0.0和P0.1,CAN2的引脚为P0.4和P0.5。
    CAN-PIN.jpg

    2) CAN设备初始化
    1. void CAN2_Init(uint32_t baud)
    2. {
    3.         CAN2_Init_Pin();
    4.         //Initialize CAN1 & CAN2
    5.         CAN_Init(LPC_CAN2, baud);
    6.         //Enable Interrupt
    7.         CAN_IRQCmd(LPC_CAN2, CANINT_RIE, ENABLE);
    8.         CAN_SetAFMode(LPC_CANAF,CAN_AccBP);

    9.         // Reset ring buf head and tail idx
    10.         __BUF_RESET(can2.rx_head);
    11.         __BUF_RESET(can2.rx_tail);

    12.         //Enable CAN Interrupt
    13.         NVIC_EnableIRQ(CAN_IRQn);
    14.         
    15.         devicecan2 = 1;
    16. }
    复制代码
    3) CAN状态查询
    返回CAN的当前状态,可以在LCD上看到状态的变化。

    4) CAN接收

    同样采用中断+消息队列的方式。
    1. /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
    2. /*********************************************************************//**
    3. * @brief                CAN_IRQ Handler, control receive message operation
    4. * param[in]        none
    5. * @return                 none
    6. **********************************************************************/
    7. void CAN_IRQHandler()
    8. {
    9.         uint8_t IntStatus;
    10.         uint32_t data,i;
    11.         CAN_MSG_Type RXMsg; // messages for test Bypass mode
    12.         
    13.         /* get interrupt status
    14.          * Note that: Interrupt register CANICR will be reset after read.
    15.          * So function "CAN_IntGetStatus" should be call only one time
    16.          */
    17.         if(        devicecan1)
    18.         {
    19.                 IntStatus = CAN_IntGetStatus(LPC_CAN1);
    20.                 //check receive interrupt
    21.                 if((IntStatus>>0)&0x01)
    22.                 {
    23.                         CAN_ReceiveMsg(LPC_CAN1,&RXMsg);
    24.                         if (!__BUF_IS_FULL(can1.rx_head,can1.rx_tail)){
    25.                                 memcpy((void *)&can1.rx[can1.rx_head],(void *)&RXMsg,sizeof(CAN_MSG_Type));
    26.                                         __BUF_INCR(can1.rx_head);
    27.                                 }
    28.                 }
    29.         }
    30.         if( devicecan2 )
    31.         {
    32.                 IntStatus = CAN_IntGetStatus(LPC_CAN2);
    33.                 //check receive interrupt
    34.                 if((IntStatus>>0)&0x01)
    35.                 {
    36.                         CAN_ReceiveMsg(LPC_CAN2,&RXMsg);
    37.                         if (!__BUF_IS_FULL(can2.rx_head,can2.rx_tail)){
    38.                                 memcpy((void *)&can2.rx[can2.rx_head],(void *)&RXMsg,sizeof(CAN_MSG_Type));
    39.                                         __BUF_INCR(can2.rx_head);
    40.                                 }
    41.                 }
    42.         }
    43. }

    44. /*********************************************************************//**
    45. * @brief                can1 read function for interrupt mode (using ring buffers)
    46. * @param[in]        UARTPort        Selected UART peripheral used to send data,
    47. *                                 should be UART0
    48. * @param[out]        rxbuf Pointer to Received buffer
    49. * @param[in]        buflen Length of Received buffer
    50. * @return                 Number of bytes actually read from the ring buffer
    51. **********************************************************************/
    52. uint32_t CAN1Receive(CAN_MSG_Type *rxbuf)
    53. {
    54.     CAN_MSG_Type *data = (CAN_MSG_Type *) rxbuf;
    55.     uint32_t bytes = 0;

    56.         /* Loop until receive buffer ring is empty or
    57.                 until max_bytes expires */
    58.         if(!(__BUF_IS_EMPTY(can1.rx_head, can1.rx_tail)))
    59.         {
    60.                 /* Read data from ring buffer into user buffer */
    61.                 memcpy(data, (void *)&can1.rx[can1.rx_tail], sizeof(CAN_MSG_Type));               

    62.                 /* Update tail pointer */
    63.                 __BUF_INCR(can1.rx_tail);

    64.                 /* Increment data count and decrement buffer size count */
    65.                 bytes++;
    66.         }

    67.     return bytes;
    68. }
    复制代码
    中断中接收CAN消息,并且填入消息队列中,通过CAN1Receive()函数每次读取一个CAN消息,直到读完为止。
    5) CAN发送
    CAN的发送采用查询式,接到上位的数据后,调用发送函数,每次发送1帧数据。
    1. void CAN1_Send(uint8_t *data)
    2. {
    3.         CAN_MSG_Type msg;
    4.         memcpy((void *)&msg.id,data,4);
    5.         if(msg.id >> 11)
    6.                 msg.format = EXT_ID_FORMAT;
    7.         else
    8.                 msg.format = STD_ID_FORMAT;
    9.         msg.len = 8;
    10.         msg.type = DATA_FRAME;
    11.         memcpy((void *)msg.dataA,data+4,4);
    12.         memcpy((void *)msg.dataB,data+8,4);
    13.         if(devicecan1)
    14.                 CAN_SendMsg(LPC_CAN1, &msg);
    15. }
    复制代码
    l  键盘及LED驱动
    键盘和LED驱动主要指I2C驱动。
    1) I2C初始化

    系统中保留I2C0作为所有I2C外设的统一接口,并用PCA9551芯片完成板载4个按键和4个LED的采集和驱动。
    I2C-PIN.jpg
            通过底板原理图和核心板原理图的对比,我们可以确定I2C0的引脚为P0.27和P0.28。
    2) 键盘

    通过这个函数,可以获取PCA9551上连接的4个板载按键输入,分别占用返回值的低4位,每一位代表一个按键输入,1表示按键输入有效,0表示按键输入无效。
    1. char GetPCA9551_Btn(void)
    2. {
    3.         uint8_t pca9551_buf[10];
    4.         uint8_t btn;
    5.         pca9551_buf[0]=0x00;
    6.         rxsetup.sl_addr7bit = PCA9551_SLVADDR;
    7.         rxsetup.tx_data = pca9551_buf;        // Get address to read at writing address
    8.         rxsetup.tx_length = 1;
    9.         rxsetup.rx_data = &btn;
    10.         rxsetup.rx_length = 1;
    11.         rxsetup.retransmissions_max = 3;

    12.         I2C_MasterTransferData(I2CDEV, &rxsetup, I2C_TRANSFER_POLLING);

    13.         btn = ~btn;
    14.         btn &= 0x0f;
    15.         return btn;
    16. }
    复制代码
    3) LED驱动

    LED驱动通过PCA9551_SetLed(uint8_tled)函数点亮板载4个LED,通过void PCA9551_ClrLed(uint8_t led)函数熄灭4个LED,LED的选择通过传入参数的第4位表示,为1表示操作有效,为0表示操作无效。
    1. void WritePCA9551(void)

    2. {

    3.      uint8_t pca9551_buf[10];

    4.      txsetup.sl_addr7bit = PCA9551_SLVADDR;

    5.      txsetup.tx_data = pca9551_buf;

    6.      txsetup.tx_length = 3;

    7.      txsetup.rx_data = NULL;

    8.      txsetup.rx_length = 0;

    9.      txsetup.retransmissions_max = 3;

    10.    

    11.      pca9551_buf[0]=0x15;

    12.      pca9551_buf[1]=0x55;

    13.      pca9551_buf[2]=Led_Status;

    14.      I2C_MasterTransferData(I2CDEV, &txsetup, I2C_TRANSFER_POLLING);

    15.    

    16. }



    17. void PCA9551_SetLed(uint8_t led)

    18. {

    19.      if(led & 0x01)

    20.          Led_Status &= ~(0x03);

    21.      if(led & 0x02)

    22.          Led_Status &= ~(0x0c);

    23.      if(led & 0x04)

    24.          Led_Status &= ~(0x30);

    25.      if(led & 0x08)

    26.          Led_Status &= ~(0xc0);



    27.      WritePCA9551();

    28. }



    29. void PCA9551_ClrLed(uint8_t led)

    30. {

    31.      if(led & 0x01)

    32.          Led_Status |= 0x01;

    33.      if(led & 0x02)

    34.          Led_Status |= 0x04;

    35.      if(led & 0x04)

    36.          Led_Status |= 0x10;

    37.      if(led & 0x08)

    38.          Led_Status |= 0x40;

    39.      WritePCA9551();

    40. }

    复制代码
    l  LCD驱动和菜单
    LCD驱动借鉴了官方提供的程序,调了几天才最终调通。

    1)LCD初始化
    1. static void LCD_Init_Pin(void)
    2. {
    3.         PINSEL_CFG_Type PinCfg;        
    4.         /* Pin configuration
    5.          * gpio: select P2.0 - P2.7 displaybus
    6.          * gpio: select P2.8 RS,P2.10 RD,P2.9 WR
    7.          */
    8.         PinCfg.Funcnum = 0;
    9.         PinCfg.OpenDrain = 0;
    10.         PinCfg.Pinmode = 0;
    11.         PinCfg.Pinnum = 0;
    12.         PinCfg.Portnum = 2;
    13.         PINSEL_ConfigPin(&PinCfg);
    14.         PinCfg.Pinnum = 1;
    15.         PINSEL_ConfigPin(&PinCfg);
    16.         PinCfg.Pinnum = 2;
    17.         PINSEL_ConfigPin(&PinCfg);
    18.         PinCfg.Pinnum = 3;
    19.         PINSEL_ConfigPin(&PinCfg);
    20.         PinCfg.Pinnum = 4;
    21.         PINSEL_ConfigPin(&PinCfg);
    22.         PinCfg.Pinnum = 5;
    23.         PINSEL_ConfigPin(&PinCfg);
    24.         PinCfg.Pinnum = 6;
    25.         PINSEL_ConfigPin(&PinCfg);
    26.         PinCfg.Pinnum = 7;
    27.         PINSEL_ConfigPin(&PinCfg);
    28.         PinCfg.Pinnum = 8;
    29.         PINSEL_ConfigPin(&PinCfg);
    30.         PinCfg.Pinnum = 10;
    31.         PINSEL_ConfigPin(&PinCfg);
    32.         PinCfg.Pinnum = 22;
    33.         PinCfg.Portnum = 0;
    34.         PINSEL_ConfigPin(&PinCfg);
    35.         
    36.         GPIO_SetDir(2, 0x00000FF | LCD_RS_BIT | LCD_E_BIT, 1);
    37.         GPIO_SetDir(0, LCD_RW_BIT, 1);
    38. }

    39. /*---------------------------------------------------------------------------*
    40. * Routine:  LCD_ActivateLCD
    41. *---------------------------------------------------------------------------*
    42. * Description:
    43. *      Turn on the char display and initialize.
    44. * Inputs:
    45. *      void
    46. *---------------------------------------------------------------------------*/
    47. void LCD_ActivateLCD(void)
    48. {
    49.         LCD_Init_Pin();
    50.     // Ensure enable is LOW
    51.          LCDE_Ctl(1);

    52.     // Put into instruction mode
    53.     // Wait at least 15 ms (we'll do 25 ms)
    54.         LCDRS_Ctl(0);
    55.     delay_ms(25);

    56.      LCD_WriteDataOrInstr(0x02);
    57.     delay_us(100);
    58.    // Two lines, 1/16 duty cycle, 5x8 dots Operation Mode
    59.     // Needs 39 uS, use 100 uS
    60.     LCD_WriteDataOrInstr(
    61.         INSTR_FUNC(IFUNC_8BIT|IFUNC_TWO_LINE|IFUNC_DISPLAY_ON));
    62.     delay_us(100);

    63.     // Display On: display on, cursor off, blinking off
    64.     // Needs 39 uS, use 100 uS
    65.     LCD_WriteDataOrInstr(
    66.         INSTR_DISPLAY(IDISPLAY_ON|IDISPLAY_CURSOR_OFF|IDISPLAY_BLINK_OFF));
    67.     delay_us(100);

    68.     LCD_WriteDataOrInstr(
    69.         INSTR_SET_DDRAM_ADDR(0));
    70.     delay_us(100);
    71.         
    72.         // Clear the display
    73.     // Needs 1.53 ms, use 5 ms
    74.     LCD_WriteDataOrInstr( INSTR_CLEAR);
    75.     delay_ms(5);

    76.     // Now go into data entry mode with auto increment and auto shift off
    77.     // Needs 39 uS, use 100 uS
    78.     LCD_WriteDataOrInstr(
    79.         INSTR_ENTRY_MODE(IENTRY_INCREMENT|IENTRY_SHIFT_OFF));
    80.     delay_us(100);

    81.     iRow = 0;
    82.     iColumn = 0;

    83. }
    复制代码
    通过底板原理图和核心板原理图的对比,我们可以确定LCD的引脚为P2.0到P2.9和P2.10,P0.22。
    LCD-PIN.jpg
    2)显示一个字符串

    该函数可以在指定的行列开始,显示一行英文字符和数字。
    1. void asc_tran(uint8_t row, uint8_t col, char *asc)
    2. {
    3.     LCD_SetCursor(col,row);
    4.     while((*asc) != 0)  
    5.     {
    6.         LCD_WriteData(*asc);
    7.         asc++;           
    8.     }
    9. }
    复制代码
    3)显示信息的菜单
    1. static void DispRefresh(void)
    2. {
    3.         int i;
    4.         LCD_ClearScreen();
    5.         for(i=0;i<4;i++)
    6.                 asc_tran(i,0,dispmenu[i]);
    7.         
    8. }
    9. void Display_M1(void)
    10. {
    11.         int i;
    12.         char btn;
    13.         if(dispflag == 0)
    14.         {
    15.                 strcpy(dispmenu[0],title);
    16.                 for(i=0;i<3;i++)
    17.                         strcpy(dispmenu[1+i],mainmenu[curptr+i]);
    18.                 DispRefresh();
    19.                 dispflag = 1;
    20.         }
    21.         btn = GetPCA9551_Btn();
    22.         switch(btn)
    23.         {
    24.                 case BTN_UP:
    25.                         if(curptr > 0)
    26.                                 curptr--;
    27.                         dispflag = 0;
    28.                         break;
    29.                 case BTN_DW:
    30.                         if(curptr < 1)
    31.                                 curptr++;
    32.                         dispflag = 0;
    33.                         break;
    34.                 default:
    35.                         break;
    36.         }
    37. }
    复制代码

    下一贴将展示上位机软件和实际的测试结果.
    上位软件和测试结果

    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-5 11:15
  • 签到天数: 1061 天

    连续签到: 1 天

    [LV.10]以坛为家III

    29

    主题

    1517

    帖子

    31

    金牌会员

    Rank: 6Rank: 6

    积分
    4979
    最后登录
    2024-5-31
     楼主| 发表于 2019-3-7 20:18:28 | 显示全部楼层
    没有采用外扩得I2C键盘,在这个设计中仅使用了板载的键盘和板载的LED灯,在上位软件和实际测试结果中将会展示LED的使用方式.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    16 小时前
  • 签到天数: 2924 天

    连续签到: 15 天

    [LV.Master]伴坛终老

    23

    主题

    4139

    帖子

    82

    金牌会员

    Rank: 6Rank: 6

    积分
    13767
    最后登录
    2025-7-20
    发表于 2019-3-8 09:11:40 | 显示全部楼层
    多谢分享,帖子好长。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 10:11
  • 签到天数: 1846 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112622
    最后登录
    2025-7-19
    发表于 2019-3-8 09:46:29 | 显示全部楼层
    支持一下~~~
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2020-4-30 21:50
  • 签到天数: 17 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    9

    主题

    142

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1208
    最后登录
    2023-2-28
    发表于 2019-3-8 10:08:51 来自手机 | 显示全部楼层
    支持一下,周末加油补贴
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3868

    主题

    7472

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    39232
    最后登录
    2025-7-18
    发表于 2019-3-8 16:55:56 | 显示全部楼层
    给楼主点个赞
    qiandao qiandao
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 10:11
  • 签到天数: 1846 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112622
    最后登录
    2025-7-19
    发表于 2019-3-9 19:25:24 | 显示全部楼层
    支持一下哎~~
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-20 20:15 , Processed in 0.172884 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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