第八章作业

一、作业内容

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

2、在ADC模块中,显示当前温度和芯片内部温度,感受温度变化(分别用冷、热触碰)。

二、源码

1、ADC实验

//======================================================================

//文件名称: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");

    

    printf("实验四第二题:显示芯片内部温度和当前温度\n");

    printf("马彬明,学号32106100115\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);

}

        num_AD1 = adc_ave(ADC_CHANNEL_1,8);

        num_AD2 = adc_ave(ADC_CHANNEL_15,8);

        num_AD3 = adc_ave(ADC_CHANNEL_TEMPSENSOR,8);

        printf("第 %d 次采集\n",mCount);

        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);

        printf("通道1(GEC47、46)的温度: %f\r\n",Regression_Ext_Temp(num_AD1));

        printf("通道15(GEC12、11)的温度:%f\r\n",Regression_Ext_Temp(num_AD2));

        printf("内部温度传感器的温度:%f\r\n\n",Regression_MCU_Temp(num_AD3));

        mCount++;      

    }  //for(;;)结尾

    //(2)======主循环部分(结尾)========================================

}   //main函数(结尾)

//======以下为主函数调用的子函数===========================================

//======================================================================

//函数名称:Delay_ms

//函数返回:无

//参数说明:无

//功能概要:延时 - 毫秒级

//======================================================================

void Delay_ms(uint16_t u16ms)

{

    uint32_t u32ctr;

    for(u32ctr = 0; u32ctr < 8000*u16ms; u32ctr++)

    {

        __ASM("NOP");

    }

}

//======================================================================

//功能概要:连续判断三次GPIO的输入引脚,大部分为0,则认为有触摸

//参数说明:GPIO引脚

//函数返回:1:有触摸,0:无触摸

//原理概要:当GPIO引脚被定义为无上下拉输入功能时,容易收到外界干扰,本程序

//         把这个特性转为有用的功能,由于人体相当于一个大电阻,手触摸这个

//         引脚会使得引脚状态发生随机性改变,利用这种变化可以被视为有触摸,

//         实现了无触摸功能引脚的触摸功能

//======================================================================

//============================================================================

//函数名称: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;

}

2、flash通信

#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 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;    //主循环次数变量

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");

    

    printf("实验四:对于有数据的某扇区,如果没有擦除(Flash_erase),可否写入新数据\n");

    printf("马彬明,学号32106100115\n");

       

//(1)======启动部分(结尾)==========================================

    

    //擦除第51扇区

flash_erase(51);   

    //向50扇区第0偏移地址开始写32个字节数据

    flash_write(51,0,32,(uint8_t *) "旧文本:马彬明学号尾数115\n");

flash_read_logic(mK1,51,0,32); //从51扇区读取32个字节到mK1中

printf("第一次读取51扇区的32字节的内容:  %s\n",mK1);

//不擦除读取51扇区

flash_write(51,0,32,(uint8_t *) "新文本:马彬明学号尾数115\n");

flash_read_logic(mK2,51,0,64);

printf("第二次不擦除读取51扇区的32字节的内容:  %s\n",mK2);

//(2)======主循环部分(结尾)========================================

}   //main函数(结尾)

三、现象

1、ADC实验

开始执行

触摸芯片观察内部温度传感器的温度:

可以看到内部温度传感器的温度由最初的摄氏6度升到10摄氏度再升到13摄氏度

触摸通道15(GEC12,11)的位置,观察其温度变化

可以看到通道15(GEC12,11)的温度由最初的16摄氏度左右逐渐上升,上升到34摄氏度左右。

触摸通道1(GEC47,46)观察其温度变化

可以看到温度由最初的16摄氏度左右逐渐上升到30摄氏度左右。

2、flash实验

在没擦除内容的情况下,是可以向扇区写内容的,实验结果显示,不擦除扇区内容直接些内容,读出来的内容是新写进去的内容,旧的内容被新的内容取代了。

四、分析思考

问题1:在做实验三时,学号尾号为15,将扇区15擦除后整个板子不亮了,也无法重启

解决问题:开发板的低扇区(0-26)的位置是bios的内容,当清除15扇区的内容后,bios就无法使用了,所以即使给板子通上电,板子也无法正确的运行程序。需要给开发板重新烧写bios程序才可以正确的运行。

问题2:在做第二题时采集的温度出现了如下的情况

分析:输出的温度不在我们日常的范围内,所以可能是输出的格式出了问题。

函数输出的结果的类型为float,所以应在输出时将输出类型变为%f

问题三:实验中遇到这样的情况,手只接触GEC47,而不接触GEC46

分析:有实验结果可以知道,这样做的时候通道一的A/D值变得很高,

实际上有代码可以得知,需要先将将 AD 值转换为对应的电压值Vtemp,再将将电压值转换为对应的电阻值Rtemp,最后将电阻值转换为实际温度值。当我直接出47的时候,会导致Vtemp变小,Rtemp变大,最终导致temp为负值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值