如果自己编写程序来处理浮点数,那是很头疼的事。还好,各种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); }