目录
目录README.md

按键程序

需求

从独立208(大底板)上通过USART接口发送传感器数据,面板208(当前项目)解析并显示。每3个8位数码管和一个按钮是一个物理量,按下按钮显示,再按下熄灭。

环境

使用沁恒官方提供的IDE MounRiver Studio进行代码编写和烧录。 (加载项目文件CH32V208RBT6.wvproj)

需要使用WCH-Link进行连接。 alt text (注意:SWCLK和SWDIO的杜邦线不能太长,否则会识别不到芯片)

208的引脚情况如下,5对应SWDIO、6对应SWCLK,9对应GND,10对应3.3V,以上用于烧录。1、2、3分别是GDN、DBG_TX、DBG_RX,以上用于调试,调试波特率为115200。 alt text

原理图及实现

原理图见 docs/frontpanel_v1.pdf,整体使用一个CH32V208RBT6芯片(文档见docs/CH32V208DS0.PDF)作为主机,多个PCA9555(文档见docs/pca9555.pdf)作为从机,使用5条I2C线进行通信。

本项目从底层实现了I2C接口(i2c.c/h),并基于此封装了pca9555(pca9555.c/h),此部分应该不需要维护,暴露的接口只有Mode、Get和Set,具体用法可见函数定义处注释。

请确保先InitPca9555(),再对led或button进行init。

所有外设抽象为 LedSegment 和 ButtonSet。

typedef struct {
    uint8_t i2c_id;  // led所属 I2C 的编号, 1 ~ 4, I2C5 为按钮线
    uint8_t address; // led所属 PCA9555 7位地址, 0x20 ~ 0x27
    uint8_t port;    // led所在 GPIO 端口, 0 ~ 1
    uint8_t data;    // led需要显示的内容, 对于数码管,指的是led_digits[]的下标 0 ~ LED_LETTER_NEG
                     // 对于普通led,指的是该端口所有led当前的亮灭情况
    uint8_t status;  // 数码管当前是否亮着  以及是否携带小数点 uuuu uuyx
                     // u为unused,末尾两位为x和y,其中x表示是否携带小数点,y表示是否亮着
                     // 普通led不使用
} LedSegment;

typedef struct {
    uint8_t i2c_id;  // 按钮集合所属 I2C 的编号, 5
    uint8_t address; // 按钮集合所属 PCA9555 7位地址, 0x20 ~ 0x27
    uint8_t port;    // 按钮集合所属 PCA9555 的端口,0 ~ 1
    uint8_t data;    // 按钮集合的数据情况
}ButtonSet;

本质上一个ButtonSet或一个LedSegment其实指的是一个PCA9555的一个GPIO口,有8位data。

对于数码管恰好占用一个GPIO口,而对于其他的LED灯和ButtonSet则需要额外对待。

LED

对于数码管(LED)而言,将其保存在全局变量all_digits_led里,每连续三个构成一组,通过 ledType * 3 + 0/1/2 来定位数码管。通过LedShowData来显示data,LedSetData来修改data。注意修改完data需要重新显示。

ButtonSet

对于按钮而言,所有button都保存在all_button里,一个ButtonSet里面还有若干个按钮。通过ButtonScan来查询一个ButtonSet里所有按钮的变化情况,如果被按下,对应位为1。

左部分按钮可以直接根据每排6个按顺序操作数码管,而剩余部分则需要通过buttontype来获得。

USART

对于接收,使用循环队列实现一个缓冲区buf,在USART3_IRQHandler中断函数中将收到的消息保存到buf中,使用ProcessAllData将会从buf中取出80个字节进行解析并修改对应数码管的data。(不满80字节则不处理)

对于发送,直接使用SendByte或SendStr。

波特率为115200。

主循环

每次先取数据解析更新数码管的data,之后扫描按钮更新数码管的显示状态,然后数码管统一进行一次显示操作(data修改或是状态更改都需要重新show,因此直接每10ms做一次重新显示)。

通信协议

独立208(大底板)和面板208(本项目)之间存在一些通信。

所有的数据按照 <deviceID> <messageID> <data> 的格式传输,其中 <deviceID> 为消息源的设备编号(1 byte),<messageID> 为数据类型标识(1 byte),<data> 为实际的数据。

所有数据均以byte流进行传输。

面板208 —–> 独立208

需要发送按钮按下的信息,这里的发送比较特殊,由于面板208仅与独立208进行通信,因此只发送一个button_id,由独立208接收后封装。 封装时也较为特殊,消息格式为 0x02 <button_id>。 其中0x02表示消息源的设备编号(面板208),button_id根据代码中enum ButtonType进行编号。

独立208 —–> 面板208

需要发送传感器数据,格式为 0x03 0x20 <data> 其中0x03表示消息源是独立208,0x20表示传输的是传感器数据,<data>为80个字节,按小端存储20个int,详见图。

后续可能还需要发送led灯数据,TO-DO。

TODO

目前,本项目一旦收到了按钮的变化,就会直接发送一条消息,而不是定时发送。

计算认知按钮使用的是拨杆,可能需要特殊处理,不能使用ButtonScan。

剩余led的意义不明,只编写了呼吸灯用于测试,目前将其保存在all_single_led数组中。

关于
4.7 MB
邀请码