第一个实验:
Main.c:
Isr.c文件:
Include.h:
第二个实验:
Main.c:
Isr.c:
第三个实验:
主要修改在main.c,增添了一个处理过程,和方向位变量,通过每次闪烁调整方向位,从而调整占空比,做到长闪和短闪的突出差异。
Main.c:
#define GLOBLE_VAR
#include "includes.h" //包含总头文件
void Delay_ms(uint16_t u16ms);
int main(void)
{
//(1.1)声明main函数使用的局部变量
uint8_t mFlag; //灯的状态标志
uint8_t Flag; //希望采集的电平高低标志
double m_duty; //占空比
uint8_t m_K; //确保每次能正确打印输出PWM波形
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.3)给主函数使用的局部变量赋初值
Flag=1;
mFlag=0; //灯的状态标志
//(1.4)给全局变量赋初值
//(1.5)用户外设模块初始化
gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF); //初始化红灯
pwm_init(PWM_USER,1500,1000,25.0,PWM_CENTER,PWM_MINUS); //PWM输出初始化
//(1.6)使能模块中断
//(1.7)【不变】开总中断
ENABLE_INTERRUPTS;
m_K=0;
m_duty=20.0; //系统定义的变量,占空比
uint8_t mzl__direction=1;// 用于控制占空比的增减方向
printf("广州大学-马志龙 高电平时 表示 80%占空比 和20% 低电平占空比 闪烁 体现在灯光停留时间,\n");
for(;;)
{
if (mzl__direction == 0)
{
m_duty = 80.0;
pwm_update(PWM_USER, m_duty);
mzl__direction = 1; // 达到80换
}
else if(mzl__direction == 1)
{
m_duty = 20.0;
pwm_update(PWM_USER, m_duty);
mzl__direction = 0; // 达到20换
}
m_K=0; // 保证每次输出打印完整的PWM波,再进入下一个循环
do
{
mFlag = gpio_get(PWM_USER);
if ((mFlag == 1) && (Flag == 1))
{
printf("high :1 !!!\n");
Flag = 0;
m_K++;
gpio_reverse(LIGHT_RED); // 小灯反转为另一个灯色
}
else if ((mFlag == 0) && (Flag == 0))
{
printf("low :0 !!!\n");
Flag = 1;
m_K++;
gpio_reverse(LIGHT_RED);
}
} while (m_K < 2);
} // for(;;)结尾
}
void Delay_ms(uint16_t u16ms)
{
uint32_t u32ctr;
for(u32ctr = 0; u32ctr < 8000*u16ms; u32ctr++)
{
__ASM("NOP");
}
}
第四个实验:
Main.c:
#define GLOBLE_VAR
#include "includes.h" //包含总头文件
void Delay_ms(uint16_t u16ms)
{
uint32_t u32ctr;
for(u32ctr = 0; u32ctr < 8000*u16ms; u32ctr++)
{
__ASM("NOP");
}
}
int main(void)
{
//(1.1)声明main函数使用的局部变量
uint8_t mFlag; //灯的状态标志
uint8_t flag; //标记高低电平
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.3)给主函数使用的局部变量赋初值
mFlag='A'; //灯的状态标志
//(1.4)给全局变量赋初值
gTime[0] = 0; //分钟
gTime[1] = 0; //秒
gTime[2] = 0; //毫秒
period = 1000; //自动重装载寄存器初始值
//(1.5)用户外设模块初始化
gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_ON); //初始化蓝灯
outcmp_init(OUTCMP_USER,3000,200,50.0,CMP_REV); //输出比较初始化
incapture_init(INCAP_USER,375,1000,CAP_DOUBLE); //上升沿捕捉初始化
systick_init(1); //设置systick为1ms中断
//(1.6)使能模块中断
cap_enable_int(INCAP_USER); //使能输入捕捉中断
//(1.7)【不变】开总中断
ENABLE_INTERRUPTS;
printf("广州大学 mzl");
for(;;) //for(;;)(开头)
{
flag = gpio_get(INCAP_USER);
//灯状态标志mFlag为'L',改变灯状态及标志
if (mFlag=='L' && flag == 1) //判断灯的状态标志
{
mFlag='A'; //灯的状态标志
gpio_set(LIGHT_BLUE,LIGHT_ON); //灯“亮”
}
//如灯状态标志mFlag为'A',改变灯状态及标志
else if(mFlag=='A' && flag == 0) //判断灯的状态标志
{
mFlag='L'; //灯的状态标志
gpio_set(LIGHT_BLUE,LIGHT_OFF); //灯“暗”
}
} //for(;;)结尾
//(2)======主循环部分(结尾)========================================
}
- 运行结果
第一个实验:
这里cTime设置的很精巧,是为什么呢,因为ctime,只需要秒数,然后通过我们的isr.c里的计算过程,更新cTime数组。这里给个例子,比如,如果直接初始化为1000秒,将自动计算到分钟,小时:
计算过程主要在这里:
接下来正式开始实验:
初始化为30秒。
进行初始化:
在打印红灯亮之后,不再打印信息,并且终止中断。往后看不到任何打印的信息,并且红灯保持亮。
用适当的文字、截图、图片等描述实验的结果。
第二个实验:
编译工程
等待闹钟,三十秒,设置的打印输出的时间和我在main函数里设置的一致。从6.7 5:20:31开始。
没到时间的时候,闪烁,蓝灯和白灯等切换:
到时间了,绿灯亮:
第三个实验:述实验的结果。
编译工程后运行;
肉眼可见的,灯光频率不一样,短的非常短,长的比较长。
第四个实验:
如图所示,连上杜邦线后,时间间隔 一开始1s亮1次,后面每次-0.1s,第二次间隔0.9s亮一次,递减到0.1s间隔亮一次后,调整会1s。
- 分析思考
嵌入式这次实验内容很多,但是原理的话其实都能懂,一定要懂原理才去动手,否则会无头苍蝇乱撞,不懂的词就得去搜索,多请教。