嵌入式作业07

1、用实验验证,对于有数据的某扇区,如果没有擦除(Flash_erase),可否写入新数据?注:扇区号为学号 后2位,数据文本中要有姓名。

程序代码如下:

main.c:

#define GLOBLE_VAR
#include "includes.h"      //包含总头文件

//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
	uint32_t mMainLoopCount;  //主循环次数变量
	uint8_t mK1[32];	 //按照逻辑读方式从指定flash区域中读取的数据
    
    //uint8_t flash_test[32]={'A','B','C','D','E','F','G',' ','t',
    //                        'o',' ','S','o','o','c','h','o','w',' ',
     //                       'U','n','i','v','e','r','s','i','t','y','!'};
	//uint8_t result;    //判断扇区是否为空标识
//(1.2)【不变】关总中断
	DISABLE_INTERRUPTS;

//(1.3)给主函数使用的局部变量赋初值
    mMainLoopCount=0;    //主循环次数变量


//(1.4)给全局变量赋初值
   
//(1.5)用户外设模块初始化
	gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_ON);	//初始化蓝灯

//(1.6)使能模块中断
   
   
//(1.7)【不变】开总中断
	ENABLE_INTERRUPTS;
       
//(1)======启动部分(结尾)==========================================
    
    //擦除第55扇区
	flash_erase(55);   
    //向55扇区第0偏移地址开始写32个字节数据
    flash_write(55,0,32,(uint8_t *) "DZW 32106100055");
	flash_read_logic(mK1,55,0,32); //从55扇区读取32个字节到mK1中
	printf("读取55扇区的32字节的内容:  %s\n",mK1);
	memset(mK1, 0, sizeof(mK1));	//内容清零
	
	if(flash_write(55,0,32,(uint8_t *) "32106100055 DZW")!=0)
		printf("不擦除会写入失败");
	else
	{
		flash_read_logic(mK1,55,0,32); //从55扇区读取32个字节到mK1中
		printf("不擦除就写入后读取55扇区的32字节的内容:  %s\n",mK1);
		memset(mK1, 0, sizeof(mK1));	//内容清零
	}
	
	//擦除第55扇区
	flash_erase(55);   
	flash_write(55,0,32,(uint8_t *) "32106100055 DZW");
	flash_read_logic(mK1,55,0,32); //从55扇区读取32个字节到mK1中
	printf("擦除再写入后读取55扇区的32字节的内容:  %s\n",mK1);
	memset(mK1, 0, sizeof(mK1));	//内容清零
	
 //(2)======主循环部分(开头)========================================
	for(;;)   //for(;;)(开头)
	{
//(2.1)主循环次数变量+1
        mMainLoopCount++;
//(2.2)未达到主循环次数设定值,继续循环
		if (mMainLoopCount<=12888999)  continue;
//(2.3.1)清除循环次数变量
		mMainLoopCount=0; 
	}
}   //main函数(结尾)

程序运行结果如下:

(1)先说实验结果,如果没有擦除,不能写入新数据,因为Flash 存储器芯片或微控制器具有硬件级别的保护机制,防止在没有擦除的情况下进行写入。这种保护机制可能会导致写入操作在硬件级别上失败,即使软件层面的函数调用返回成功。

(2)先修改flash.c的内容,flash_write函数内置了扇区擦除功能,我将其注释掉,使其不能自行擦除,并且对flash_best函数的返回值进行了判断,若flash_best函数执行失败则直接返回1。

(3)然后在main.c编写程序

①先是正常的擦除再写入内容,接着读取内容再打印,最后再将内容清零。

②然后尝试不擦除扇区就写入新内容,如果软件层面检测到写入失败,则会显示“写入失败”,如果检测写入成功,则会读取内容再打印。

③最后尝试擦除扇区再写入新内容。

(4)现在运行程序,查看实验结果

①从第二行结果可以看出,不擦除时写入失败了,扇区中还是上一次写入的内容。

②但是从程序的返回值来看,返回值为0,程序认为写入成功了,所以第二行显示的内容是这个而不是“写入失败”

③第三行可以看出擦除后再写入新数据成功了,打印的内容也是正确的。

④从上述结果可以得出结论:如果没有擦除,不能写入新数据,因为Flash 存储器芯片或微控制器具有硬件级别的保护机制,防止在没有擦除的情况下进行写入。这种保护机制可能会导致写入操作在硬件级别上失败,即使软件层面的函数调用返回成功。


2、在ADC实验中,结合热敏电阻,分别通过触摸芯片表面和热敏电阻,引起A/D值变化,显示芯片内部温度和当前温度。

程序代码如下:

main.c:

#define GLOBLE_VAR
#include "includes.h"      //包含总头文件
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;  //主循环次数变量
    uint16_t num_AD2;
    uint16_t num_AD3;
    uint16_t temp_AD2;
    uint16_t temp_AD3;
    //(1.2)【不变】关总中断
    DISABLE_INTERRUPTS;
    
    //(1.3)给主函数使用的局部变量赋初值
    mMainLoopCount=0;    //主循环次数变量
    
    //(1.4)给全局变量赋初值
    
    //(1.5)用户外设模块初始化
    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;
     
    //(1)======启动部分(结尾)==========================================
    
    //(2)======主循环部分(开头)========================================
    for(;;)   //for(;;)(开头)
    {
        //(2.1)主循环次数变量+1
        mMainLoopCount++;
        //(2.2)未达到主循环次数设定值,继续循环
        //延时1秒
        if (mMainLoopCount<=3000000)  continue;
        //(2.3)达到主循环次数设定值,执行下列语句,进行灯的亮暗处理
        //(2.3.1)清除循环次数变量
        mMainLoopCount=0;
        num_AD2 = adc_ave(ADC_CHANNEL_15,8);
        num_AD3 = adc_ave(ADC_CHANNEL_TEMPSENSOR,8);
        temp_AD2 =Regression_Ext_Temp(num_AD2);      //环境温度AD值转为实际温度
		temp_AD3=Regression_MCU_Temp(num_AD3);		//芯片温度AD值转为实际温度
        printf("环境温度的A/D值:%d\r\n",num_AD2);
        printf("环境温度:%d\r\n",temp_AD2);
        printf("内部温度传感器的A/D值:%d\r\n",num_AD3);   
        printf("内部温度:%d\r\n",temp_AD3);
        Delay_ms(1000);
    }  //for(;;)结尾
    //(2)======主循环部分(结尾)========================================
}   //main函数(结尾)

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+8; 
}


//============================================================================
//函数名称: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+8;
}

程序运行结果如下:

        首先初始化ADC通道15和17,通道15对应热敏电阻引脚,可以用来获得环境温度AD值;通道17对应内部温度传感器,可以获得芯片内部温度AD值。

        然后通过Regression_Ext_Temp和Regression_MCU_Temp函数将获得的环境和芯片内部温度AD值转化为实际温度。

        运行程序后发现测量温度值和实际温度值有较大差距,这里用一种较简单的方式缩小差距。

        接下来进行串口更新,打开串口,运行结果如下:

        然后给热敏电阻降温,运行结果如下:

        可以看到环境温度的AD值逐渐上升,环境温度逐渐下降。

        现在再用手触摸热敏电阻,使热敏电阻升温

        可以看到环境温度的AD值逐渐下降,环境温度逐渐上升。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值