/*******************************************************************************/ // 功能:模拟信号 转 数字信号 (电压采集) /*******************************************************************************/ // 头文件 宏定义 #include <iostm8s003f3.h> #include"stdio.h" /*******************************************************************************/ //常用数据类型定义 #define u8 uint8_t #define u16 uint16_t #define u32 uint32_t typedef unsigned char uint8_t; typedef unsigned int uint16_t; typedef unsigned long uint32_t; /*******************************************************************************/ //端口/引脚定义区域 // HC595 各 移位数据 输出并口控制 RCK #define RCLK_1 PC_ODR_ODR6 = 1 #define RCLK_0 PC_ODR_ODR6 = 0 // HC595 时钟端口 控制 SCK #define CLK_1 PC_ODR_ODR7 = 1 #define CLK_0 PC_ODR_ODR7 = 0 // HC595 数据端口 控制 SER #define DAT_1 PD_ODR_ODR2 = 1 #define DAT_0 PD_ODR_ODR2 = 0 /*******************************************************************************/ //用户自定义数据区域 static u16 AD_Vtemp[10] = {0}; // 装载 10次 ADC 采样数据 static u16 AD_val = 0; // ADC 单次 采样数据 static u16 GET_voltage = 0; // 获取到的 电压 const u16 SET_V = 1500; // 使用 const常量 定义电压 阈值 const u16 V_ref = 5210; // 使用 const常量 定义 当前电压参考值 const u16 Low_V = 1000; // 使用 const常量 定义 低电压 阈值 const u16 Heigh_V = 4000; // 使用 const常量 定义 高电压 阈值 /*******************************************************************************/ //用户自定义数据区域 //数码管 0 ~ F 的代码数组 unsigned char const Data[16] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e}; // 值( 7位 段码 共阳 ); unsigned char const Wu[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; // 位( 要不断的扫描); u8 number[8], SMGtimes, SMGBit; u16 ms_count; u8 time_n = 0; /*******************************************************************************/ //函数声明区域 void delay(u16 Count); //延时函数 void delay18B20(u16 Count); //DS18B20延时函数 void ADC_init(void); void ADC_GET(void); void AVG_AD_Vtemp(void); void HC595_WriteData(u8 data , u8 wu); /******************************************************************************* **函数名称:void HC595_WriteData(u8 data , u8 wu) **功能描述:数码管显示 **入口参数:data->要显示的数据 , wu->设置要第几位数码管显示 **输出:无 *******************************************************************************/ void HC595_WriteData(u8 data , u8 wu) { u8 i; u16 tempdata; tempdata = (u16)(wu); // 先把8位码放入16位里 tempdata <<= 8; // 把8位位码移到高8位先发送 tempdata |= data; // 再把段码8位放在低8位发送 RCLK_0; // 先把输出存储锁存时钟线拉低 for(i = 0 ; i < 16 ; i++) { CLK_0; // 数据输入时钟线拉低 if(tempdata & 0x8000) // 判断数据,把数据架在输出数据位上 { DAT_1; } else { DAT_0; } CLK_1; // 把时钟线拉高,把移位数据输入并移位 tempdata <<= 1; // 把新数据架在输出数据线上 } CLK_0; RCLK_1; // 把输出存储锁存时钟线拉高,把595的移位数据输出到并口 } /******************************************************************************* **函数名称:Init_NumericDisplay() **功能描述:初始化位码控制芯片和段码控制芯片74HC164D的时钟和数据 相应的IO控制参数初始化 **入口参数:无 **输出:无 *******************************************************************************/ void Init_NumericDisplay() { //2片 HC595 芯片 引脚初始化 PC_DDR_DDR6 = 1; // 输出方向 PC_CR1_C16 = 1; // 推挽输出 PC_CR2_C26 = 1; // 高速10MHZ //2片 HC595 芯片 引脚初始化 PC_DDR_DDR7 = 1; // 输出方向 PC_CR1_C17 = 1; // 推挽输出 PC_CR2_C27 = 1; // 高速10MHZ //HC595 芯片 引脚初始化 PD_DDR_DDR2 = 1; // 输出方向 PD_CR1_C12 = 1; // 推挽输出 PD_CR2_C22 = 1; // 高速10MHZ } /********************************************************************** * 函数: Init_CLK(void) * 功能: 时钟设置;配置成 16MHz; * 输入: 无; * 输出: 无; ***********************************************************************/ void Init_CLK(void) { CLK_CKDIVR = 0x00; // 配置成 16MHz; } /********************************************************************** * 函数: Delay_Nms(u16 x) * 功能: 延时Nms; * 输入: int x; * 输出: 无 ***********************************************************************/ void Delay_Nms(u16 x) { u16 a,b; while(x--) { for(a=0;a<18;a++) { for(b=0; b<176; b++); // 175->998us; 176->1.00425ms; } } } /********************************************************************** * 函数: Delay_Nus(u16 x) * 功能: 延时Nms; * 输入: int x; * 输出: 无 ***********************************************************************/ void Delay_Nus(u16 i) { u8 j; while(i--) { for(j=0; j<3; j++) //10us基准延时程序 { ; } } } /******************************************************************************* **函数名称:Init_TIM4() **功能描述:定时器2 参数初始化 **入口参数:无 **输出:无 *******************************************************************************/ void Init_TIM4() { TIM4_IER_UIE = 0; //先禁止定时器4更新中断 TIM4_EGR_UG = 0; // TIM4_PSCR_PSC = 7; //定时器4时钟 = 16MHz / 128 = 125KHZ TIM4_ARR = 125; //设定1定时器产生1毫秒重装载时的计数值,255是最大值 TIM4_CNTR = 0x00; //设定计数器的初值 TIM4_SR_UIF = 0; // 清除 更新中断标志 TIM4_SR_TIF = 0; // 清除 触发中断标志 TIM4_CR1_CEN = 1; // 使能 定时器4 TIM4_CR1_ARPE = 1; // 使能 预装载寄存器缓冲 TIM4_IER_UIE = 1; // 使能 更新 中断 } /********************************************************************** * 函数: ADC_init(void) * 功能: ADC2初始化流程“七步走”函数ADC_init(),无形参,无返回值 * 输入: 无; * 输出: 无; ***********************************************************************/ void ADC_init(void) { // 1.选择模拟通道,按需配置中断 ADC_CSR = 0x04; //选择通道 PD3-AIN4 ,禁止中断 PD3-AIN4 0000 0100 // 2.配置分频系数,明确转换模式 ADC_CR1 = 0x02; //配置 预分频 为 fMaster/2,连续转换 模式 0 000 00 1 0 // 3.配置触发事件,明确对齐方式 ADC_CR2 = 0x08; //禁止外部触发,数据 右对齐(先读低再读高) 0000 1000 //ADC_CR2=0x00; //禁止外部触发,数据 左对齐(先读高再读低) // 4.初始配置模拟通道(无中断悬浮输入) PD_DDR_DDR3 = 0; //配置PE6端口为输入模式 PD_CR1_C13 = 0; //配置PE6端口为悬浮输入模式 PD_CR2_C23 = 0; //配置PE6端口禁止外部中断 // 5.按需禁止/使能施密特触发器功能 ADC_TDRL= 0x00; // 使能 斯密特 触发器 // 6.使能 ADC 上电唤醒 并 禁用I/O输出功能 ADC_CR1 |= 0x01; // 首次将ADON位 置1 用于唤醒 //7.启动ADC转换并获取转换数据 //ADC_GET(); // 用户编写的ADC转换函数 } /********************************************************************** * 函数: ADC_GET(void) * 功能: ADC2模数转换函数 ADC_GET(),无形参,无返回值 * 输入: 无; * 输出: 无; ***********************************************************************/ void ADC_GET(void) { u8 num = 0; // 循环控制 变量,用于控制次数 ADC_CR1 = 0x02; // 配置 预分频为 fMaster/2,连续转换模式 ADC_CR1 |= 0x01; // 首次将 ADON位 置1 用于 唤醒 ADC_CR1 |= 0x01; // 再次将 ADON位 置1 用于 启动ADC转换 while(num < 10) // 采 10次 结果 (采集 10次 数据) { while((ADC_CSR & 0x80) == 0); // 待 ADC 转换 结束 ADC_CSR &= 0x7F; // 清除 ADC 转换完成标志位 AD_Vtemp[num] = (u16)ADC_DRL; // 先将ADC转换数据低位赋值 AD_Vtemp[num] |= (u16)ADC_DRH << 8; // 再将左移8位后的高位数据与原低位数据进行或连接 //(高位数据)+(低位数据)= 完整ADC采样数据结果 num ++; // 循环控制变量自增 } ADC_CR1 &= 0xFD; // 关闭ADC转换 } /********************************************************************** * 函数: ADC_GET(void) * 功能: 平均值滤波函数AVG_AD_Vtemp(),无形参,无返回值 * 输入: 无; * 输出: 无; ***********************************************************************/ void AVG_AD_Vtemp(void) { u8 i, j; // 定义排序用内外层循环变量i和j u16 temp; // 定义中间“暂存”变量temp for(i=10; i>=1; i--) // 外层循环 { for(j=0; j<(i-1); j++) // 内层循环 { if(AD_Vtemp[j] > AD_Vtemp[j+1]) // 数值比较 (排序) { temp = AD_Vtemp[j];// 数值换位 AD_Vtemp[j] = AD_Vtemp[j+1]; AD_Vtemp[j+1] = temp; } } } for(i=2; i<=7; i++) // 2,3,4,5,6,7 去掉2个最低去掉2个最高 { AD_val += AD_Vtemp[i]; // 将 中间6个数值 累加 } AD_val = (u16)(AD_val / 6); // 累加和 求 平均值 } /********************************************************************** * 函数: main() * 功能: 主函数 * 输入: 无; * 输出: 无; ***********************************************************************/ void main(void) { asm("sim"); // disable all interrupt EA=0; // 关闭 中断; // Init_GPIO(); // 设置 PA PB 的初始状态; Init_CLK(); // 系统时钟初始化设置 16MHz; Init_TIM4(); // 调用 定时器4 初始化函数,通过定时器的 中断控制 来显示数码管 Init_NumericDisplay(); // 调用数码管驱动初始化函数,配置驱动芯片HC595对应IO口 ADC_init() ; asm("rim"); // 打开总中 while(1) { ADC_GET(); // 获取 ADC 数据 采集; AVG_AD_Vtemp(); // 取平均值; GET_voltage = (u16)(AD_val*4.882825); AD_val = 0; // 清 0 ADC 转换 数据; // qian = GET_vltage / 1000; // bei = GET_vltage % 1000 / 100; // shi = GET_vltage % 100 / 10; // ge = GET_vltage % 10; } } #pragma vector = 25 //设置 定时器4 重载的中断向量号 = 25 __interrupt void Inter_TIM4(void) { TIM4_SR_UIF = 0; // 清除 中断标志 ms_count ++; // 中断使 ms_count++ 做加法,记录 1毫秒 产生的中断次数 if(ms_count >= 2) // 2毫秒 点亮 一位 数码管 , 就是快速显示,等于 16毫秒 显示完 8个数码管,我们人眼 根本反应不过来,感觉是 8位数码管 同时显示 { ms_count = 0; number[0] = GET_voltage / 1000; // 百位; number[1] = GET_voltage % 1000 / 100; // 十 位; number[2] = GET_voltage % 100 / 10; // 个 位; HC595_WriteData(~Data[number[SMGtimes]] , ~Wu[SMGtimes]); //往数码管发送显示一个数码显示数据 // 在 0,1,2 数据间 SMGtimes ++; if(SMGtimes >= 3) // 3位 数据 在 0, 1, 2位显示 { SMGtimes = 0 ; } } }
联系人:客服在线
手机:全工:13903011251
电话:李R:13530006400
邮箱:729986191@qq.com
地址: GUANGDONG PROVINCE