完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
想在 LCD 上显示 2 或 3 位小数。
例如,显示 22,5;黄金 22.50;黄金22,500。 但想显示 22,57;例如,22,524。// MCU : PIC 16F887// External clock : Quartz 4 MHz// LED YELLOW is connected to pin 17 (portc.b2).// LED GREEN is connected to pin 18 (portc.b3).// Switch is connected to pin 21 (portd.b2).// Switch is connected to pin 22 (portd.b3).// LM35 temperature sensor : pin GND to GND,// pin DQ to pin 5 (AN3),// pin VCC to VCC./******************************************************************************///#include // A re tester en décochant dans View > Library Manager > C_Math. // Fonction floor() dans float_to_ASCII_with_2_decimals_v4/******************************************************************************/// LCD module connections : // VSS (pin 1) -> GND // VDD (pin 2) -> VCC // VEE (pin 3) -> middle pin contrast potentiometersbit LCD_RS at RB4_bit; // RS (pin 4) -> portB.b4 (pin 37)// RW not used. // RW (pin 5) -> GNDsbit LCD_EN at RB5_bit; // EN (pin 6) -> portB.b5 (pin 38) // D0 (pin 7) -> GND // D1 (pin 8) -> GND // D2 (pin 9) -> GND // D3 (pin 10) -> GNDsbit LCD_D4 at RB0_bit; // D4 (pin 11) -> portB.b0 (pin 33)sbit LCD_D5 at RB1_bit; // D5 (pin 12) -> portB.b1 (pin 34)sbit LCD_D6 at RB2_bit; // D6 (pin 13) -> portB.b2 (pin 35)sbit LCD_D7 at RB3_bit; // D7 (pin 14) -> portB.b3 (pin 36) // (pin 15) -> GND // (pin 16) -> GNDsbit LCD_RS_Direction at TRISB4_bit;sbit LCD_EN_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB0_bit;sbit LCD_D5_Direction at TRISB1_bit;sbit LCD_D6_Direction at TRISB2_bit;sbit LCD_D7_Direction at TRISB3_bit;/******************************************************************************/#define CMD 0#define DATA 1#define LCD_PORT PORTB#define LCD_COLUMNS 16/******************************************************************************/// Declaration of variables :char texte[64]; // 0 to 255 // Variables ci-dessous sorties du main() pour les déclarer en global. // Le PIC 16F a moins de mémoire RAM et ROM que le PIC 18F.unsigned char *pointeur_de_char; // Déclaration d'un pointeur (*) de char "pointeur_de_char".unsigned char i;char ROW[] = {0x80, 0xC0};/******************************************************************************/// Routines :void ADC_initialization(){ ADCON0 = 0b01000001; // b0 = 1 (ADON) : le convertisseur A/N interne est activé. // b1 (GO/DONE) : A/D Conversion Status bit. // b2, b3, b4, b5 (CHS0, CHS1, CHS2, CHS3) : Analog Channel Select bits. // b6 = 1 (ADSC0), b7 = 0 (ADSC1) : fosc / 8 = 4 MHz / 8 = 0,5 MHz = 500 KHz // tosc = 1 / fosc = 1 / 500 KHz = 0,002 mS = 2 uS. // 2 uS est le temps de conversion A/D d'un bit, TAD. // Pour une conversion totale sur 10 bits il faut 12 TAD. // Pour une conversion correcte il faut que TAD = 1,6 uS au minimum. // TAD = 2 uS / bit. 12 TAD = 24 uS pour 10 bits. ADCON1 = 0b10000000; // b0 = b1 = b2 = b3 = 0 : Unimplemented. Read as '0'. // b4 = 0 (VCFG0) : Voltage reference VDD. // b5 = 0 (VCFG1) : Voltage reference VSS. // b6 = 0 : Unimplemented. Read as '0'. // b7 = 1 : ADFM (A/D result ForMat) = 1 (format justifié à droite). // Explication : // ADRESH | ADRESL // b7|b6|b5|b4|b3|b2|b1|b0|b7|b6|b5|b4|b3|b2|b1|b0 // 0| 0| 0| 0| 0| 0| r| r| r| r| r| r| r| r| r| r // les 6 MSB = 0 | résultat r sur 10 bits}unsigned int ADC_read(unsigned char channel)// Si message d'erreur "'ADC_read' Identifier redefined" pendant compilation, dans Library Manager décocher ADC_Read.// ADC_read est ma propre routine écrite pour apprentissage. Je n'utilise pas ADC_Read de la librairie Mikroelektronika.{ static unsigned int k; // Variable locale (static). ADCON0 = ADCON0 & 0b11000011; // ADCON0 = 01000001 // & 11000011 (masque) // ADCON0 = 01000001 // masque : // b0 = 1 (ADON) : pour prendre en compte l'état du convertisseur A/D, en service (0) ou à l'arrêt (1). // b1 = 1 (GO/DONE) : pour prendre en compte l'état de la conversion A/D, en cours (1) ou terminée (0). // b2 = b3 = b4 = b5 = 0 (CHS0 CHS1 CHS2 CHS3) : pour re initialiser au premier canal de conversion, le canal 0 (CHS0 = CHS1 = CHS2 = CHS3 = 0). // b6 = b7 = 1 (ADSC0 ADSC1) : pour prendre en compte la valeur du diviseur, de la vitesse de conversion, choisi. channel = channel << 2; // Décalage channel de 2 bits à gauche pour placer la valeur de channel dans bits b2 b3 b4 b5 (CHS0 CHS1 CHS2 CHS3). ADCON0 = ADCON0 | channel; // OU logique bit à bit entre ADCON0 et channel. // ou ADCON0 |= channel; Delay_ms(2); // Délais de 2 mS minimum. >>> A ajuster si besoin. <<< ADCON0.GO_DONE = 1; // Déclenchement de la conversion A/N. // ou ADCON0.b2 = 1; _asm NOP; // Recommandé par Microchip. while (ADCON0.GO_DONE == 1); // Attendre que le bit GO.DONE passe à 0. { k = ADRESL + (ADRESH * 256); // XXX A REVOIR XXX //ou k = ADRESL + (ADRESH << 8); } return(k);}void LCD_E_Pulse(void){ LCD_EN = 1; Delay_us(8); // Delay between 5 uS and 10 uS. LCD_EN = 0; Delay_us(500); // Delay between 5 uS and 1000 uS (1 mS).}void LCD_Write(unsigned char cmd_or_data, unsigned char byte){ unsigned char low, high; high = (byte >> 4) & 0x0F; // b7 b6 b5 b4 of byte are shifted to b3 b2 b1 b0 of byte and saved in high. low = byte & 0x0F; // b3 b2 b1 b0 of byte are saved in low. LCD_PORT = high; // Send higher nibble of byte to the LCD. LCD_RS = cmd_or_data; LCD_E_Pulse(); LCD_PORT = low; // Send lower nibble of byte to the LCD. LCD_RS = cmd_or_data; LCD_E_Pulse();}void StrConstRamCpy(unsigned char *dest, const code char *source) // Copie le texte de la FLASH ROM vers la RAM.{ while (*source)*dest ++ = *source ++; *dest = 0; // Terminateur "0" fin de chaine de caractère.}void LCD_Write_String(char *msg) // Variante avec pointeur msg non modifié.{ int k; k = 0; while(*(msg + k) > 0) { LCD_Write(DATA, (*(msg + k))); // Data pointée par (msg + k). k++; if (k == LCD_COLUMNS) break; // Si k = 16 sortie de la boucle while ... }}void LCD_Write_String_At(char line, char column, char *msg){ LCD_Write(CMD, ROW[line]|(column & 0x0F)); // Print message on desired line and desired column. LCD_Write_String(msg); // OK.}void print_float_v11(char *flt, long number, char decimals){ if (number < 0) { number = - number; *(flt) = '-'; } else { *(flt) = ' '; } if (decimals == 0) { *(flt + 1) = ' '; *(flt + 2) = number / 10000 + '0'; *(flt + 3) = ((number % 10000) / 1000) + '0'; *(flt + 4) = ((number % 1000) / 100) + '0'; *(flt + 5) = ((number % 100) / 10) + '0'; *(flt + 6) = (number % 10) + '0'; *(flt + 7) = ' '; *(flt + 8) = ' '; *(flt + 9) = ' '; *(flt + 10) = ' '; *(flt + 11) = ' '; *(flt + 12) = ' '; } if (decimals == 1) { *(flt + 1) = ' '; *(flt + 2) = number / 10000 + '0'; *(flt + 3) = ((number % 10000) / 1000) + '0'; *(flt + 4) = ((number % 1000) / 100) + '0'; *(flt + 5) = ((number % 100) / 10) + '0'; *(flt + 6) = ','; *(flt + 7) = (number % 10) + '0'; *(flt + 8) = ' '; *(flt + 9) = ' '; *(flt + 10) = ' '; *(flt + 11) = ' '; *(flt + 12) = ' '; } if (decimals == 2) { *(flt + 1) = ' '; *(flt + 2) = number / 10000 + '0'; *(flt + 3) = ((number % 10000) / 1000) + '0'; *(flt + 4) = ((number % 1000) / 100) + '0'; *(flt + 5) = ((number % 100) / 10) + '0';; *(flt + 6) = ','; *(flt + 7) = (number % 10) + '0'; *(flt + 8) = '0'; *(flt + 9) = ' '; *(flt + 10) = ' '; *(flt + 11) = ' '; *(flt + 12) = ' '; } if (decimals > 2) { *(flt + 1) = ' '; *(flt + 2) = number / 10000 + '0'; *(flt + 3) = ((number % 10000) / 1000) + '0'; *(flt + 4) = ((number % 1000) / 100) + '0'; *(flt + 5) = ((number % 100) / 10) + '0';; *(flt + 6) = ','; *(flt + 7) = (number % 10) + '0'; *(flt + 8) = '0'; *(flt + 9) = '0'; *(flt + 10) = ' '; *(flt + 11) = ' '; *(flt + 12) = ' '; } //i = 0; // OK. i = 2; // OK. while(flt[i] != ',') { if (flt[i] == '0') { portc.b3 = 1; // Green LED ON. flt[i] = ' '; if (flt[i - 2] == '-') { flt[i - 2] = ' '; flt[i - 1] = '-'; } if (flt[i + 1] == ',') { portc.b2 = 1; // Yellow LED ON. flt[i] = '0'; } } else { break; } i++; }}void LCD_Init_v4 (void){ Delay_ms(15); // LCD power ON initialization time >= 15 mS. LCD_Write(CMD, 0x30); // 4 datas bits > Initialization of LCD with nibble method (4 datas bits). LCD_Write(CMD, 0x02); // 4 datas bits > Initialization of LCD with nibble method (4 datas bits). LCD_Write(CMD, 0x28); // 4 datas bits > 2 lines display, 5 × 8 dot character font. LCD_Write(CMD, 0x0C); // 4 datas bits > Display ON. Cursor OFF. LCD_Write(CMD, 0x06); // 4 datas bits > Auto increment cursor. LCD_Write(CMD, 0x01); // 4 datas bits > Clear display. Delay_ms(1); // Ajustable ... (indispensable, sinon affichage erratique à la mise sous tension)}/******************************************************************************/void main(){ PORTB = 0; // Initialisation du PORT B à 0. PORTC = 0; // Initialisation du PORT C à 0. PORTD = 0; // Initialisation du PORT D à 0. ANSEL = 0b00001000; // b3 = 1 (ANS3) : sets pin 5 (AN3) as analog input. ANSELH = 0b00000000; TRISB = 0b00000000; // PORT B : b0 à b7 configurés en sortie. TRISC = 0b00000000; // PORT C : b0 à b7 configurés en sortie. TRISD = 0b00000000; // PORT D : b0 à b7 configurés en sortie. C1ON_bit = 0; // CMC1CON register > b7 > C1ON bit = 0 > Disable comparator 1. C2ON_bit = 0; // CMC2CON register > b7 > C1ON bit = 0 > Disable comparator 2. SCS_bit = 0; // OSCCON register > b0 > SCS bit = 0 > External oscillator (quartz) is used as a clock source. LCD_Init_v4 (void); pointeur_de_char = &texte[0]; // pointeur_de_char pointe sur le premier élément du tableau "texte", soit texte[0]. // Autrement dit, pointeur_de_char contient l'adresse (&) de texte[0]. do { float adc; float volt, temp; char txt[13]; ADC_initialization(); TRISD = 0x00; while(1) { adc = (ADC_read(3)); // Reads analog values. volt = adc * 4.88281; // Converts it into the voltage. temp = volt / 10.0; // Gets the temperature values. temp = temp - 273; // Converts Farenheit to Celcius. StrConstRamCpy(pointeur_de_char, "Temperature ... "); // OK. LCD_Write_String_At(0, 0, pointeur_de_char); // OK. Voir dans void LCD_Write_String(char *msg), le while(*(msg + k) > 0). //print_float_v11(&txt[0], temp, 0); //print_float_v11(&txt[0], temp, 1); print_float_v11(&txt[0], temp, 2); //print_float_v11(&txt[0], temp, 3); LCD_Write_String_At(1, 0, &txt[0]); // Write txt in 2nd row, starting at 1st digit. LCD_Write_String_At(1, 12, " °C"); // Write " °C" in 2nd row, starting at 13th digit. delay_ms(3000); } } while(1);} |
|
相关推荐
1个回答
|
|
根据编译器的不同,“int”可能只有 8 位,而它们在程序中用作 16b 位。
使用显式变量大小是最安全的。如果您使用 stdint.h 定义,例如 #include < stdint.h>这应该允许您使用诸如 int8_t、int16_t、uint8_t、uint16_t等。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
298 浏览 1 评论
《DNESP32S3使用指南-IDF版_V1.6》第二十六章 INFRARED_RECEPTION实验
309 浏览 0 评论
826 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1911 浏览 2 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
1427 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12031 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 04:38 , Processed in 0.638997 second(s), Total 73, Slave 56 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号