如果自己编写程序来处理浮点数,那是很头疼的事。还好,各种C语言开发平台都有现成的浮点数处理函数,而且CodeVisionAVR还提供了浮点数转换成字符串形式的函数,让像我这样的“小白菜”爽死了:)!本文就是用CodeVisionAVR写的一个显示浮点数的小程序,还涉及到了MAX7219及AVR单片机的SPI串行口的运用,供广大“小白菜”参考。
MAX7219是SPI串行接口的数码管驱动芯片,内部集成了段驱动器、位驱动器、数据保存器(实现静态显示)、BCD译码器、多路扫描器(单独修改某位数字)等,可驱动8位LED数码管或可以驱动64只发光二极管,节省大量的IO引脚。其特点如下:
附:Proteus仿真结果
/*****************************************************
Author: Benny
Chip type: ATmega16L
Clock frequency: 8.000000 MHz
知识点:浮点数显示、max7219、SPI
*****************************************************/
#include <avr/io.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define LOAD_PORT PORTB
void send(uchar addr, uchar data)
{
//PB3接Max7219的load引脚
LOAD_PORT &= ~(1 << 3); //拉低load
spi(addr);
spi(data);
LOAD_PORT |= (1 << 3); //拉高load
}
#define DECODE_MODE 0X09
#define INTENSITY0X0A
#define SCAN_LIMIT0X0B
#define SHUTDOWN0X0C
#define DISPLAYTEST 0X0F
void max7219_init(uchar decode_bits)
{
// decode_bits如:0b01001111中 1:decode0:nodecode
send(SHUTDOWN, 0x01); //从Shutdown模式进入Normal
send(DECODE_MODE, decode_bits); //设置需要转换成BCD码的位
send(SCAN_LIMIT, 0x07); //共有8只LED(或8位一体)
send(INTENSITY, 0x09); //亮度
send(DISPLAYTEST, 0x00); //测试
}
void display_float(float data, uchar bits)
{
/*bits:小数位数,必须是1,2,3,4,5*/
uchar i, dot_position;
uchar arr[16];
for (i = 0; i < 16; i++) {
arr[i] = 0;
}
ftoa(data, bits, arr); //将浮点数转换成字符串
for (i = 0; i < 9; i++) {
if (arr[i] == ''.'') {
dot_position = i;
}
}
for (i = 0; i < 8; i++) {
if (i == dot_position - 1) {
send(i + 1, arr[i] | 0x80); //个位数+小数点
}
else if (i >= dot_position) {
if (i {
send(i + 1, arr[i + 1]); //小数点后bits个数字
}
else {
send(i + 1, 0x7f); //无效位关闭显示
}
}
else {
send(i + 1, arr[i]); //十位以上的数字
}
}
}
void spi_init(void)
{
PORTB = 0x00;
DDRB = 0xB8;
ACSR = 0x80;
SFIOR = 0x00;
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 2000.000 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR = 0x50;
SPSR = 0x00;
}
void main(void)
{
spi_init();//初始化SPI串行口
max7219_init(0b11111111);//8位都初始化为max7219内部译成七段码模式
display_float(123.4567891, 5); //显示结果为123.45678
while (1);
}