HNU 电子实训 BSP 模块应用训练笔记

题目与 BSP 版权属于学校,代码请见 https://git.cyp0633.icu/cyp0633/eecs-bsp-test-code-2,遵循 GPLv3 协议。

1. 串口 1 收发

计算机上利用串口助手,设置串口参数:“2400,8,N,1”(即:波特率 2400bps,8 个数据位。无奇偶校验位,一个停止位),顺序发送 10 字节的 HEX 数据到 STC-B 板,STC-B 板将接收到的 10 字节数据再以倒序方式经串口 1 发送回计算机。

引入串口 1 使用的头文件 uart1.h,初始化传递波特率 2400 作为参数。然后设定接收条件,接收缓冲区指向一个空的大小为 10 的字符数组,匹配字符串指向一个空指针,设置字符串长度为 0,字符串长度为 0。并设置回调函数,当读取到符合上述条件的串口 1 数据包时,调用 sendBack 函数。

c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void sendBack()
{
    char temp;
    int i;
    for(i=0;i<5;i++)
    {
        temp=buffer[i];
        buffer[i]=buffer[9-i];
        buffer[9-i]=temp;
    }
    Uart1Print(buffer,10);
}

大致就是将 buffer 中的字符串首尾调换,然后通过串口 1 重新发回。

2. 串口 2 通信

两块 STC-B 板 1 和 2 通过串口 2 连接(485 接口上:A、B、GND,或 EXT 上:P1.0(RXD)、P1.1(TXD)、GND),设置串口 2 参数:“1200,8,N,1”。STC 板 1 往 STC 板 2 发送 5 字节数据,STC 板 2 接收数据,计算它们的累加和,并将累加和的低 8 位通过 LED 灯显示,验证结果是否正确?(STC-B 板 1 需多换几组数据验证)。

发送端

使用 Uart2Init 函数初始化串口 2,设定 RS485,波特率 1200,设置每 1s 调用回调函数 sendData

sendData 中,通过一个 countdown 全局变量设定每 10s 发送一次 buffer 中的内容(1、3、5、7、9),并将里面的每个数递增 1(溢出时设为 0x1)。

接收端

初始化串口 2,波特率 1200,初始化屏幕,并设置串口 2 接收缓冲区和回调函数,类似于题 1。

在回调函数中使用一个 for 循环计算累加和,并将其与 0xff 的计算结果传入 LedPrint 显示在 LED 上。

3. 红外无线通信

与第 2 题的操作一致,仅两块 STC-B 板通信方式选用 IR 红外无线连接(而不是串口 2)。注意:同一房间内,同时开启红外通信可能会互相干扰。

发送端

头文件引入红外,使用 IrInit 初始化红外为 NEC 格式,每 1s 设置调用回调函数。

回调函数内容与题 2 发送端类似,但考虑到红外特性将发送延迟设置为 3s。

接收端

使用 IrInit 初始化红外为 NEC 格式,使用 SetIrRxd 指定缓冲区,然后设置收到数据包的回调函数。

在回调函数中行为类似于题 2 的接收端。

4. 实时时钟

初始化 DS1302 实时时钟芯片,并将其 “时分秒” 信息以 “时时—分分—秒秒” 格式显示在数码管上。然后验证 “STC-B 学习板” 上的实时时钟在断电后,其时钟靠板上的纽扣电池仍能正常走时。

c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
struct_DS1302_RTC time, temp;
unsigned char display[8];

void changeClock()
{
    temp = RTC_Read();
    display[0] = temp.second & 0x0f;
    display[1] = (temp.second>> 4) & 0x0f;
    display[2] = temp.minute & 0x0f;
    display[3] = (temp.minute>> 4) & 0x0f;
    display[4] = temp.hour & 0x0f;
    display[5] = (temp.hour>> 4) & 0x0f;
    display[6] = temp.day & 0x0f;
    display[7] = (temp.day>> 4) & 0x0f;
    Seg7Print(display[7], display[6], display[5], display[4], display[3], display[2], display[1], display[0]);
}

void main()
{
    time.year = 0x22;
    time.day = 0x22;
    time.month = 0x8;
    time.hour = 0x15;
    time.minute = 0x33;
    time.second = 0x22;
    DS1302Init(time);
    DisplayerInit();
    SetDisplayerArea(0, 7);
    LedPrint(0);
    SetEventCallBack(enumEventSys10mS, changeClock);
    MySTC_Init();
    while (1)
    {
        MySTC_OS();
    }
}

5. 非易失存储

数据可以在掉电情况下保留在非易失存储器(M24C02 或 DS1302)中的某个单元上。设计一段小程序:上电后,读取出非易失存储内某个单元数据,并将其值显示在 LED 灯上,再将这个数据 + 1 后写回这个单元。分析这样的程序,如果拔插 “STC—B 学习板” 电源(或按板上 “RST” 复位按键),会出现什么现象?(说明:DS1302 需要靠纽扣电池才能在掉电时保存数据)

初始化 NVM 后使用 NVM_Read 读取 0x05 处的值作为初始值,并显示在 LED 上。如果值为 0xf,则重置为 0,否则将值自增 1 后写回 0x05。这样的步骤在每次重置后都会进行,就实现了自增的效果。

6. 收音机

初始化启用 FM_radio 模块。收音机参数设定为 91.8MHz,音量 6。PHONE 接口上插上耳机验证是否正确收到电台?

初始化一个 struct_FMRadio 结构体,设置频率 918,音量 6,三个 GP 都为 0,然后传递给 FMRadioInit 函数。

7. 音乐播放器

用 Music 模块提供的 API 实现播放一段音乐。

使用 SetMusic 指定节拍、音调、乐谱数据、乐谱大小(用 sizeof 得到)以及显示方式,然后使用 SetPlayerMode 开始播放。

代码存放于 https://git.cyp0633.icu/cyp0633/eecs-bsp-test-code/src/branch/master/music2

8. 温度值计算

10 位精度采集热敏电阻 ADC 值,编写程序(查表、或线性插值方法等)换算出正确温度值,并在数码管显示出来。热敏电阻参数 10K/3950,(具体见 “案例测试” 中提供的参考资料。可设有效换算温度范围 - 5°C~+85°C)。

从其他示例程序找到了一个 8 位采样值到温度的的换算表:

c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
int code tempdata[] = {239, 197, 175, 160, 150, 142, 135, 129, 124, 120, 116, 113, 109, 107, 104, 101,
                       99, 97, 95, 93, 91, 90, 88, 86, 85, 84, 82, 81, 80, 78, 77, 76,
                       75, 74, 73, 72, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, 63, 62,
                       61, 61, 60, 59, 58, 58, 57, 57, 56, 55, 55, 54, 54, 53, 52, 52,
                       51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44,
                       43, 43, 42, 42, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37,
                       36, 36, 36, 35, 35, 34, 34, 34, 33, 33, 32, 32, 32, 31, 31, 31,
                       30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25,
                       24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19,
                       19, 19, 18, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14,
                       13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 8, 7,
                       7, 7, 6, 6, 5, 5, 54, 4, 3, 3, 3, 2, 2, 1, 1, 1, 0, 0, -1, -1, -1,
                       -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9,
                       -10, -10, -11, -11, -12, -13, -13, -14, -14, -15, -16, -16, -17,
                       -18, -19, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
                       -30, -32, -33, -35, -36, -38, -40, -43, -46, -50, -55, -63, 361};

使用 ADCexpEXT 初始化 ADC,并初始化屏幕。每 10ms 回调 calcTemp 函数。

在 calcTemp 中,将 10 位取样右移 2 位变为 8 位,计算 100 次取样的累加和,并取平均值。将换算表中平均采样值的对应值显示在数码管上。

9. 扩展模板

外设模块中超声波、编码器、电子尺… 选取一个,能在数码管上显示相应物理量数值。

引入扩展模块头文件,使用 EXTInit 初始化超声波模块,初始化屏幕,设置 10ms 回调 showDist 函数。

使用 GetUltraSonic 获得超声波传感器的读数,将每位分出来显示在数码管上。

10. 直流电机

设计简单程序段,用两组参数(“50% 速度、正转”,和 “30% 速度、反转”)分别设置直流电机,并接上直流电机观察不同参数时电机转动情况。

设一个状态变量,按 Key 1 后更改其值,并输出另一种 PWM 信号。正转 50% 使用 SetPWM(0, 0, 50, 500);,反转 30% 使用 SetPWM(50, 300, 0, 0);