一.实验目的
(1)熟悉定时中断计时的工作及编程方法
(2)理解定时器模块的输入捕捉、输出比较、脉宽调制(PWM)功能的基本原理。
(3)掌握定时器模块的输入捕捉、输出比较、脉宽调制(PWM)编程方法。
(4)理解 PWM 占空比的含义。
(5)进一步深入理解 MCU 和 C#串口通信的编程方法。
二.实验内容
1.验证性实验
1)验证样例程序(ch07-Timer)中(TPM-Timer),主要功能是实现通过开发板上 TPM0计数,10ms 产生一次中断,每中断 100 次累加计时,并通过调试串口输出“MCU 记录的相对时间:00:00:01”,“00:00:01”为中断记录的时间,同时蓝色指示灯闪烁一次。
实验步骤如下:
(1)将样例 TPM-Timer 程序下载至目标板;
(2)将“TTL-USB 串口线”的“USB 端口”接 PC 机的 USB 口,串口线的串口接开发板上的串口 2(3 根,RX 接蓝线,TX 接白线,GND 接黑线);
(3)打开串口调试工具或 ch06-UART 文件夹中的“C#2010 串口测试程序”进行串口通信测试;
(4)分析理解 main.c 程序和中断服务例程 isr.c。
2)验证样例程序(ch07-Timer)中(TPM-incap-outcomp-pwm),主要功能是实现在 TPM1中断服务例程中,改变 TPM1 模块通道 0 占空比,使其占空比从 0.0 逐渐变大到 100.0,再从 100.0 逐渐变小到 0.0,如此反复,可以通过示波器看到 PTA4 输出的方波占空比的变化,从小到大再从大到小,循环执行。将 TPM0 的第 0 通道 PTC1 引脚配置为输出比较功能,TPM2 的第 0 通道 PTA1 引脚配置为输入捕捉功能,将输出比较引脚 PTC1 连接至 PTA1 输入捕捉引脚,通过调试串口输出捕捉值。
实验步骤如下:
(1)将样例 TPM-incap-outcomp-pwm 程序下载至目标板;
(2)通过导线将输出比较引脚 PTC1 连接至 PTA1 输入捕捉引脚;
(3)将“TTL-USB 串口线”的“USB 端口”接 PC 机的 USB 口,串口线的串口接开发板上的串口 2(3 根,RX 接蓝线,TX 接白线,GND 接黑线);
(4)打开串口调试工具或 ch06-UART 文件夹中的“C#2010 串口测试程序”进行串口通信测试;
(5)分析理解 main.c 程序和中断服务例程 isr.c。
2.设计性实验
(1)复制样例程序(TPM-Timer),利用该程序框架实现:通过串口调试工具或 ch06-UART 文件夹中的“C#2010 串口测试程序”发送当前系统时间如:“10:55:12”来设置开发板上的初始计时时间。
请在实验报告中给出 MCU 端程序 main.c 和 isr.c 流程图及程序语句。
(2)复制样例程序(TPM-incap-outcomp-pwm),利用该程序框架实现:将开发板上的接绿灯的引脚设为 PWM 功能,通过串口调试工具或 ch06-UART 文件夹中的“C#2010 串口测试程序”发送数值 0~100,改变绿灯的亮度。
请在实验报告中给出 MCU 端程序 main.c 和 isr.c 流程图及程序语句。
3.进阶实验★
(1)复制样例程序(TPM-Timer),利用该程序框架实现:通过 C#程序界面显示系统当前时间,通过按钮发送当前系统时间给 MCU 来设置开发板上的初始计时时间,MCU 将计时时间发送给 C #进行显示。C#界面设计如如图 1 所示。不断电运行一段时间后,请给出MCU 和 PC 系统时间的误差是多少?
请在实验报告中给出 MCU 端程序 main.c 和 isr.c 流程图及程序语句和 C#方主要程序段。
三.实验步骤和结果
1.验证性实验
(1)对中断函数以及main函数的理解
中断函数:
中断函数主要实现时间的累加。由于10ms产生一次中断,所以每经过100次中断则时间累加1s。在中断函数中通过g_time数组保存当前的时间,通过SecAdd1()函数实现对时间数组g_time的1s累加。
Main函数:
Main首先初始化定时器构件,设定其中断周期,之后对g_time数组进行初始化(初始化为00:00:00),每当时间发生变化(即g_time数组不等于上次记录下的时间)时,控制小灯改变亮暗,同时将时间输出到串口调试助手上。
2.设计性实验
(1)通过串口发送时间,设置开发板上的初始计时时间
思路分析:
- 在原代码中,g_time数组是用来记录时间的,每隔一秒,便会在中断中增加一秒。
- 通过串口,用组帧的方式,将时间发送到传口,串口获取时间后,将时间传到g_time数组中,则g_time便会继续增加时间。
流程图:
串口中断函数流程图:
主函数流程图:
具体代码如下:
串口中断代码:
void UART2_IRQHandler(void)
{
uint_8 ch;
uint_8 flag = 1;
DISABLE_INTERRUPTS;
ch = uart_re1(UART_2, &flag);
if (1 == flag)
{
g_flag=CreateFrame(ch,g_getTime);
uart_send1(UART_2, ch);
}
ENABLE_INTERRUPTS;
}
主函数代码:
if (g_flag) {
g_flag=0;
g_time[0] = g_getTime[2] * 10 + g_getTime[3];
g_time[1] = g_getTime[5] * 10 + g_getTime[6];
g_time[2] = g_getTime[8] * 10 + g_getTime[9];
remember=g_time[2];
printf("\r\n初始时间设置成功!时间设置为:%02d:%02d:%02d",g_time[0],g_time[1],g_time[2]);
}
if (g_time[2] != remember) //判断秒钟是否发生变化
{
light_change(LIGHT_BLUE); //蓝色运行指示灯状态变化
printf("\r\nMCU记录的相对时间:%02d:%02d:%02d", g_time[0], g_time[1],
g_time[2]);
remember = g_time[2];
}
(2)通过TPM程序的PWM功能改变duty值来控制小灯亮度
思路分析:
- Duty的值是由三位数决定的,而串口发送的是字符串,并且每一个字符存在不同位置。
- 由分析可知,首先将组帧中duty三位数的值分别减去’0’字符
- 其次将三位数分别乘以对应的权值相加,获取duty值,
- 最后将duty值传到update函数中
流程图:
串口中断函数:
Main函数:
s
具体代码如下:
串口函数:
void UART2_IRQHandler(void)
{
uint_8 ch;
uint_8 flag = 1;
DISABLE_INTERRUPTS;
ch = uart_re1(UART_2, &flag);
if (1 == flag)
{
g_flag=CreateFrame(ch,g_buffer);
uart_send1(UART_2, ch);
if(g_getTime[0]=='P'&&g_buffer[1]==1){
g_getDuty=g_ buffer [2]-'0';
}else if(g_getTime[0]=='P'&&g_ buffer [1]==2){
g_getDuty=(g_ buffer [2]-'0')*10+(g_ buffer [3]-'0');
}else if(g_getTime[0]=='P'&&g_ buffer [1]==3){
g_getDuty=(g_ buffer [2]-'0')*100+g_ buffer [3]-'0')*10+(g_ buffer [4]-'0');
}
}
ENABLE_INTERRUPTS;
}
Update部分:
duty=g_getDuty;
tpm_clear_int(1); //清TPM1的溢出中断标志
pwm_update(TPM1_CH0,duty); //PWN更新
3.进阶实验★
(1)通过C#实现一个按钮,获取系统当前时间,并且通过串口发送给开发板,设置开发板计时时间,并继续计时。
思路分析:
- 设计实验1已经实现MCU获取时间以其为初始时间计时,则本次实验主要实现C#部分的代码即可
- C#中,在form中添加一个按钮,在按钮的响应事件中获取当前系统的时间,并且把当前系统的时间通过组帧的方式发送到串口中。
C#界面设计:
流程图:
串口中断函数流程图:
主函数流程图:
具体代码如下:
串口程序及主程序同设计性实验1,C#程序如下:
按钮响应事件:
private void button1_Click(object sender, EventArgs e)
{
string t = DateTime.Now.ToLongTimeString().ToString();
string s;
if (t.Length == 7)
{
s = "P80" + t + "C";
}else
{
s = "P8" + t + "C";
}
this.TbSCISend.Text = s;
BtnSCISend_Click(sender, e);
}
不断电运行一段时间(11分钟)之后发现,MCU发来的时间变慢,较实际时间相差5分钟左右。
四.实验总结(需加入心得体会)
通过本次实验,我熟悉了定时器的工作原理,学会了定时中断计时的编程方法,理解了PWM占空比的含义及使用方法,同时进一步深入理解了MCU和C#通信的编程方法。在实验过程中,我对于PWM占空比理解一直有偏差,在同学的帮助下,我更加深入的理解了占空比的原理,也让我明白了同学之间互相帮助能够使彼此都获得更大的进步。
来源:CSDN
作者:林决明
链接:https://blog.csdn.net/qq_40883804/article/details/103049159