1、2个或以上同学相互连接,利用CAN通信,向对方发送带有本人姓名的信息。连线方式:按基本原理性电路(不带收发器芯片)连接,参考教材图10-1
#define GLOBLE_VAR
#include "includes.h" //包含总头文件
//----------------------------------------------------------------------
//声明使用到的内部函数
//main.c使用的内部函数声明处
//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
vuint32_t mMainLoopCount; //主循环次数变量
uint8_t mFlag; //灯的状态标志
uint32_t mLightCount; //灯的状态切换次数
uint32_t localMsgID;
uint32_t txMsgID;
uint32_t BitRate;
uint8_t buff;
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.3)给主函数使用的局部变量赋初值
mMainLoopCount=0; //主循环次数变量
mFlag='A'; //灯的状态标志
mLightCount=0; //灯的闪烁次数
localMsgID = 0x0AU;
txMsgID = 0x0BU;
BitRate = 36;
//(1.4)给全局变量赋初值
//(1.5)用户外设模块初始化
gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_ON); //初始化蓝灯
emuart_init(UART_User,115200);
uart_init(UART_3,115200);
//【***CAN模块初始化***】
can_init(CAN_1,localMsgID,BitRate);
//(1.6)使能模块中断
uart_enable_re_int(UART_User);
uart_enable_re_int(UART_3);
//【***使能CAN模块中断***】
can_enable_recv_int(CAN_1);
//(1.7)【不变】开总中断
ENABLE_INTERRUPTS;
//(1)======启动部分(结尾)==========================================
//(2)======主循环部分(开头)========================================
for(;;) //for(;;)(开头)
{
//(2.1)主循环次数变量+1
mMainLoopCount++;
//(2.2)未达到主循环次数设定值,继续循环
if (mMainLoopCount<=12889000) continue;
//(2.3)达到主循环次数设定值,执行下列语句,进行灯的亮暗处理
//(2.3.1)清除循环次数变量
mMainLoopCount=0;
//(2.3.2)如灯状态标志mFlag为'L',灯的闪烁次数+1并显示,改变灯状态及标志
if(can_send(CAN_1,txMsgID,8,(uint8_t*)"Iamyjf") !=0) printf("failed\r\n");
else printf("success!");
if(can_recv(CAN_1,&buff) !=0) printf(buff);
} //for(;;)结尾
//(2)======主循环部分(结尾)========================================
} //main函数(结尾)
2、在ADC实验中,结合热敏电阻,分别通过触摸芯片表面和热敏电阻,引起A/D值变化,显示芯片内部温度和当前温度。
//======================================================================
//文件名称:main.c(应用工程主函数)
//框架提供:SD-Arm(sumcu.suda.edu.cn)
//版本更新:20191108-20200419
//功能描述:见本工程的..\01_Doc\Readme.txt
//移植规则:【固定】
//======================================================================
#define GLOBLE_VAR
#include "includes.h" //包含总头文件
//----------------------------------------------------------------------
//声明使用到的内部函数
//main.c使用的内部函数声明处
void Delay_ms(uint16_t u16ms);
float Regression_Ext_Temp(uint16_t tmpAD); //环境温度AD值转为实际温度
float Regression_MCU_Temp(uint16_t mcu_temp_AD); //MCU温度AD值转为实际温度
//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
uint32_t mMainLoopCount; //主循环次数变量
uint8_t mFlag; //灯的状态标志
uint32_t mCount; //延时的次数
uint32_t mLightCount; //灯的状态切换次数
uint16_t num_AD1;
uint16_t num_AD2;
uint16_t num_AD3;
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.3)给主函数使用的局部变量赋初值
mMainLoopCount = 0; //主循环次数变量
mFlag = 'A';
mLightCount = 0; //灯的闪烁次数
mCount = 0; //记次数
//(1.4)给全局变量赋初值
//(1.5)用户外设模块初始化
gpio_init(LIGHT_BLUE, GPIO_OUTPUT, LIGHT_ON); //初始化蓝灯
adc_init(ADC_CHANNEL_1, AD_DIFF); //初始化ADC通道1,
adc_init(ADC_CHANNEL_15, AD_DIFF); //初始化ADC通道15
adc_init(ADC_CHANNEL_TEMPSENSOR, AD_SINGLE); //初始化ADC通道:内部温度
emuart_init(UART_User, 115200);
//(1.6)使能模块中断
uart_enable_re_int(UART_User);
//(1.7)【不变】开总中断
ENABLE_INTERRUPTS;
printf("------------------------------------------------------\n");
printf("金葫芦提示: \n");
printf("(1)目的:ADC单端输入与差分输入测试 \n");
printf("(2)单端:内部温度传感器,通道号17,无需引脚对应 \n");
printf(" 差分:GEC引脚47、46(通道1、2) \n");
printf(" GEC引脚12、11(通道15、16) \n");
printf("(3)测试方法:单端:手摸芯片表面,A/D值增大,不要摸 \n");
printf(" 到引脚,静电可能损坏芯片 \n");
printf(" 差分:将引脚47接地、46接3.3V,观察通道1情况\n");
printf(" 将引脚46接地、47接3.3V,观察通道1情况\n");
printf(" 类似方法,观察通道15 \n");
printf("------------------------------------------------------\n");
//(1)======启动部分(结尾)==========================================
//(2)======主循环部分(开头)========================================
for(;;) //for(;;)(开头)
{
//(2.1)主循环次数变量+1
mMainLoopCount++;
//(2.2)未达到主循环次数设定值,继续循环
//延时1秒
if (mMainLoopCount <= 3000000) continue;
//(2.3)达到主循环次数设定值,执行下列语句,进行灯的亮暗处理
//(2.3.1)清除循环次数变量
mMainLoopCount = 0;
//(2.3.2)如灯状态标志mFlag为'L',灯的闪烁次数+1并显示,改变灯状态及标志
if (mFlag == 'L') //判断灯的状态标志
{
mLightCount++;
mFlag = 'A'; //灯的状态标志
gpio_set(LIGHT_BLUE, LIGHT_ON); //灯“亮”
Delay_ms(1000);
}
//(2.3.3)如灯状态标志mFlag为'A',改变灯状态及标志
else
{
mFlag = 'L'; //灯的状态标志
gpio_set(LIGHT_BLUE, LIGHT_OFF); //灯“暗”
Delay_ms(1000);
}
// 读取ADC值
num_AD1 = adc_ave(ADC_CHANNEL_1, 8);
num_AD2 = adc_ave(ADC_CHANNEL_15, 8);
num_AD3 = adc_ave(ADC_CHANNEL_TEMPSENSOR, 8);
// 打印ADC值及对应的温度值
printf("通道1(GEC47、46)的A/D值: %d\r\n", num_AD1);
printf("通道15(GEC12、11)的A/D值:%d\r\n", num_AD2);
printf("内部温度传感器的A/D值:%d\r\n", num_AD3);
float ext_temp = Regression_Ext_Temp(num_AD2);
float mcu_temp = Regression_MCU_Temp(num_AD3);
printf("当前温度(外部热敏电阻):%.2f℃\r\n", ext_temp);
printf("芯片内部温度:%.2f℃\r\n\n", mcu_temp);
mCount++;
} //for(;;)结尾
//(2)======主循环部分(结尾)========================================
} //main函数(结尾)
//======以下为主函数调用的子函数===========================================
//======================================================================
//函数名称:Delay_ms
//函数返回:无
//参数说明:无
//功能概要:延时 - 毫秒级
//======================================================================
void Delay_ms(uint16_t u16ms)
{
uint32_t u32ctr;
for (u32ctr = 0; u32ctr < 8000 * u16ms; u32ctr++)
{
__ASM("NOP");
}
}
//============================================================================
//函数名称:Regression_Ext_Temp
//功能概要:将读到的环境温度AD值转换为实际温度
//参数说明:tmpAD:通过adc_read函数得到的AD值
//函数返回:实际温度值
//============================================================================
float Regression_Ext_Temp(uint16_t tmpAD)
{
float Vtemp, Rtemp, temp;
if (tmpAD <= 72)
{
return -274; // 无效值
}
Vtemp = (tmpAD * 3300.0) / 4096;
Rtemp = Vtemp / (3300.0 - Vtemp) * 10000.0;
temp = (1 / (log(Rtemp / 10000.0) / 3950.0 + (1 / (273.15 + 25)))) - 273.15 + 0.5;
return temp;
}
//============================================================================
//函数名称:Regression_MCU_Temp
//功能概要:将读到的MCU温度AD值转换为实际温度
//参数说明:mcu_temp_AD:通过adc_read函数得到的AD值
//函数返回:实际温度值
//============================================================================
float Regression_MCU_Temp(uint16_t mcu_temp_AD)
{
float mcu_temp_result;
mcu_temp_result = (float)(55 + (100 * ((float)(mcu_temp_AD) - AD_CAL1)) / (AD_CAL2 - AD_CAL1));
return mcu_temp_result;
}
//========================================================================
/*
知识要素:
(1)main.c是一个模板,该文件所有代码均不涉及具体的硬件和环境,通过调用构件
实现对硬件的干预。
(2)本文件中对宏GLOBLE_VAR进行了定义,所以在包含"includes.h"头文件时,会定
义全局变量,在其他文件中包含"includes.h"头文件时,
编译时会自动增加extern
*/
3、用实验验证,对于有数据的某扇区,如果没有擦除(Flash_erase),可否写入新数据?注:扇区号为学号 后2位,数据文本中要有姓名。
//======================================================================
//文件名称:main.c(应用工程主函数)
//框架提供:SD-Arm(sumcu.suda.edu.cn)
//版本更新:20191108-20200419
//功能描述:见本工程的..\01_Doc\Readme.txt
//移植规则:【固定】
//======================================================================
#define GLOBLE_VAR
#include "includes.h" //包含总头文件
//----------------------------------------------------------------------
//声明使用到的内部函数
//main.c使用的内部函数声明处
//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
uint32_t mMainLoopCount; //主循环次数变量
uint8_t mFlag; //灯的状态标志
uint32_t mLightCount; //灯的状态切换次数
uint8_t mK1[32]; //按照逻辑读方式从指定flash区域中读取的数据
uint8_t mK2[32]; //按照物理读方式从指定flash区域中读取的数据
uint8_t mK3[32]; //实验数据变量
uint8_t flash_test[32]={'A', 'B', 'C', 'D', 'y', 'j', 'f', ' '};
uint8_t new_data[32] = {'H', 'e', 'l', 'l', 'o', ' ', 'y', 'j', 'f', ' '};
uint8_t result; //判断扇区是否为空标识
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.3)给主函数使用的局部变量赋初值
mMainLoopCount=0; //主循环次数变量
mFlag='A'; //灯的状态标志
mLightCount=0; //灯的闪烁次数
//(1.4)给全局变量赋初值
//(1.5)用户外设模块初始化
gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_ON); //初始化蓝灯
//(1.6)使能模块中断
//(1.7)【不变】开总中断
ENABLE_INTERRUPTS;
printf("------------------------------------------------------\n");
printf("金葫芦提示: \n");
printf("(1)目的:flash扇区读写数据测试 \n");
printf("(2)测试过程:两种读写数据方式 \n");
printf(" 第一种:使用flash_write向50扇区写入一串字符串 \n");
printf(" 再用flash_read_logic将字符串读出,并用printf打印 \n");
printf(" 第二种:使用flash_write_physical向32扇区写入一串字符串\n");
printf(" 再用flash_read_physical将字符串读出,并用printf打印 \n");
printf("------------------------------------------------------\n");
//(1)======启动部分(结尾)==========================================
result = flash_isempty(12,MCU_SECTORSIZE); // 判断第12扇区是否为空
printf("第12扇区是否为空,1表示空,0表示不空:%d\n",result);
//初始化12扇区
flash_erase(12);
flash_write(12, 0, 32, flash_test);
printf("写入数据前读取12扇区的内容: %s\n", mK3);
flash_read_logic(mK3, 12, 0, 32); // 从12扇区读取32个字节到mK3中
result = flash_isempty(12,MCU_SECTORSIZE); // 判断第12扇区是否为空
printf("第12扇区是否为空,1表示空,0表示不空:%d\n",result);
// 在没有擦除的情况下写入新的数据
flash_write(12, 0, 32, new_data);
printf("未擦除情况下写入新数据后读取12扇区的内容: %s\n", mK3);
flash_read_logic(mK3, 12, 0, 32); // 从12扇区读取32个字节到mK3中
result = flash_isempty(12,MCU_SECTORSIZE); // 判断第12扇区是否为空
printf("第12扇区是否为空,1表示空,0表示不空:%d\n",result);
//擦除情况下写入新数据
flash_erase(12);
result = flash_isempty(12,MCU_SECTORSIZE); // 判断第12扇区是否为空
printf("第12扇区是否为空,1表示空,0表示不空:%d\n",result);
flash_write(12, 0, 32, new_data);
printf("写入数据前读取12扇区的内容: %s\n", mK3);
flash_read_logic(mK3, 12, 0, 32); // 从12扇区读取32个字节到mK3中
result = flash_isempty(12,MCU_SECTORSIZE); // 判断第12扇区是否为空
printf("第12扇区是否为空,1表示空,0表示不空:%d\n",result);
//(2)======主循环部分(开头)========================================
for(;;) //for(;;)(开头)
{
} //for(;;)结尾
//(2)======主循环部分(结尾)========================================
} //main函数(结尾)
//======以下为主函数调用的子函数===========================================
//========================================================================