标题:
iar for avr 编程 通过 仿真数码管显示不全 请求指导
[打印本页]
作者:
by64214
时间:
2021-3-1 20:04
标题:
iar for avr 编程 通过 仿真数码管显示不全 请求指导
学习《AVR单片机与传感器模块设计》(IAR) 教材,ATMega16 的A/D转换编程实践
编程通过 但是仿真 显示不全
1.jpg
(82.42 KB, 下载次数: 48)
下载附件
2021-3-1 19:59 上传
2.jpg
(82.47 KB, 下载次数: 51)
下载附件
2021-3-1 20:01 上传
#include <iom16.h>
unsigned char const SEG7[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //用数组来预存数码管显示字符0~9的花样数据
unsigned char const ACT[4] = {0x01,0x02,0x04,0x08}; //定义动态扫描位的变量以及接收到数据标志 0xfe,0xfd,0xfb,0xf7
unsigned int dis_val; //定义显示变量
unsigned char i; //定义动态扫描位的变量
//===========================端口初始化=======================================
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00; //PORTA初始化为悬浮输入
PORTB = 0xff;
DDRB = 0xff;
PORTC = 0xff;
DDRC = 0xff;
}
//===========================ADC初始化========================================
void adc_init(void)
{
ADCSRA = 0xEE; //使能ADC、开始转换、自动触发、使能中断、8预分频
ADMUX = 0x40; //使用AVCC做基准电压源、数据格式为右对齐、选择通道0
}
//============================定时器0初始化===================================
void timer0_init(void)
{
TCNT0 = 0x83; //定时1ms的初始值
TCCR0 = 0x03; //64预分频
TIMSK = 0x01; //使能定时器0溢出中断
}
//=============================设备初始化=====================================
void init_devices(void)
{
port_init(); //调用端口初始化
timer0_init(); //调用定时器0初始化
adc_init(); //调用ADC初始化
SREG = 0x80; //打开全局中断
}
//===============================A/D转换======================================
unsigned int ADC_Convert(void)
{
unsigned int temp1,temp2;
temp1 = (unsigned int)ADCL; //先读取低8位数据
temp2 = (unsigned int)ADCH; //再读取高8位数据
temp2 = (temp2<<8)+temp1; //高8位左移两位与低8位合并成10位数据
return(temp2); //返回合并后的值
}
//==============================数据转换======================================
unsigned int conv(unsigned int i)
{
long x;
unsigned int y;
x = (4840*(long)i)/1023; //把变量转化成需要显示的形式
y = (unsigned int)x; //把无符号长整型变量强制转换成无符号整型变量
return y; //返回转换后的值
}
//==============================主函数========================================
void main(void)
{
init_devices(); //调用设备初始化
while(1)
{
; //空循环
}
}
//=======================中断函数(定时器0溢出中断)============================
#pragma vector = TIMER0_OVF_vect
__interrupt void TIMER0_OVF_Server(void)
{
TCNT0 = 0x83; //重载初值
if(++i>3) //扫描位数为4位
i = 0;
switch(i)
{
case 0:PORTB = SEG7[dis_val%10]; //送个位待显示的数据
PORTC = ACT[0]; //打开个位显示(点亮)
break;
case 1:PORTB = SEG7[(dis_val/10)%10]; //送十位待显示的数据
PORTC = ACT[1]; //打开十位显示(点亮)
break;
case 2:PORTB = SEG7[(dis_val/100)%10]; //送百位待显示的数据
PORTC = ACT[2]; //打开百位显示(点亮)
break;
case 3:PORTB = SEG7[dis_val/1000]&0x7F; //送千位待显示的数据并点亮小数点
PORTC = ACT[3]; //打开千位显示(点亮)
break;
}
}
//=======================中断函数(A/D转换结束中断)============================
#pragma vector = ADC_vect
__interrupt void ADC_Server(void)
{
dis_val = conv(ADC_Convert()); //获取A/D转换数据并送显
}
复制代码
作者:
wulin
时间:
2021-3-1 21:32
从图片现象看是显示函数没有消隐导致乱码,实际电路不会出现乱码但会有鬼影。添加消隐代码。
//=======================中断函数(定时器0溢出中断)============================
#pragma vector = TIMER0_OVF_vect
__interrupt void TIMER0_OVF_Server(void)
{
TCNT0 = 0x83; //重载初值
if(++i>3) //扫描位数为4位
i = 0;
PORTC = 0x00;//消隐
switch(i)
{
case 0:PORTB = SEG7[dis_val%10]; //送个位待显示的数据
PORTC = ACT[0]; //打开个位显示(点亮)
break;
case 1:PORTB = SEG7[(dis_val/10)%10]; //送十位待显示的数据
PORTC = ACT[1]; //打开十位显示(点亮)
break;
case 2:PORTB = SEG7[(dis_val/100)%10]; //送百位待显示的数据
PORTC = ACT[2]; //打开百位显示(点亮)
break;
case 3:PORTB = SEG7[dis_val/1000]&0x7F; //送千位待显示的数据并点亮小数点
PORTC = ACT[3]; //打开千位显示(点亮)
break;
}
}
复制代码
作者:
by64214
时间:
2021-3-2 13:01
谢谢指导! 正常显示了
请问 显示有误差,怎样提高精度 x = (4840*(long)i)/1023; 4840 有的程序不是这个值!
非常感谢!!!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1