greetings
i build project using 16f877 and seiko lcd (l167100j00) 1x16 char.
i try long hard but only get 8 digits to display. i sur it only minor problem for someone knowing more than me. hoping to get answer.
my grateful for help. sorry bad english,hope you able understand.
seb
metal.c
/ / nom: metal.C
/ / date: 07 / 08 / 2004
/ / version: 1.00
/ / circuit: circuit final detecteur pi
/ / auteur: sj
/ / micro: pic16f877 7.3728mhz - > tcycl = 0.5425 us
/ / = = = = = = = = = = = = = = = = = = = = = = = = = =
#include "metal.h"
#include "lcd.h"
/ / #include "string.h"
/ / fusibles de configuration, eeprom interne(256 octets), n°identification
__config(wdtdis & hs & pwrten & unprotect & bordis & lvpdis & debugdis) ;
/ / eeprom interne: 256 octets max
/ / __eeprom_data(0, 1, 2, 3, 4, 5, 6, 7) ;
#Define version1 "* Seb PI Metal *\n\r"
#Define version2 "(c)by Seb 07-08-2004\n\r"
/ / __idloc(1234) ;
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / macro blocage interruptions
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ *
static Bit tmpgie2; / / flag pour GIE
#Define flag_gie_save2 tmpgie2 = 0;if(GIE) tmpgie2 = 1;gie = 0;
#Define flag_gie_rest2 If(tmpgie2) GIE = 1;
/ / Save + rest = 7 rom
* /
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / thus all the 'persistent' variables will be kept together, and you can
/ / get the bounds of this psect from the following declarations:
/ / pour stockage permanent en eeprom des variables utiliser:
/ / read_from_eeprom(_lnvram, _hnvram - _lnvram) ;
/ / write_to_eeprom(_lnvram, _hnvram - _lnvram) ;
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
extern char _lnvram[], _hnvram[];
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / essayer de passer sur 7bits!!!!
/ / * definition des 8 caracteres en cg - ram * / /
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Const char cg_ram[] =
{0x0e, 0x11, 0x0e, 0x14, 0x0f, 0x04, 0x1a, 0x02, / / 0x00 bon.gauche
0x0e, 0x11, 0x0e, 0x05, 0x1e, 0x04, 0x0b, 0x08, / / 0x01 bon.droit
0x0e, 0x11, 0x0e, 0x04, 0x1f, 0x04, 0x0a, 0x11, / / 0x02 bon.milieu
0x20, 0x20, 0x15, 0x20, 0x1f, 0x20, 0x20, 0x20, / / 0x03 continu =
0x20, 0x0a, 0x15, 0x20, 0x1f, 0x20, 0x20, 0x20, / / 0x04 alternatif ~_
0x18, 0x14, 0x14, 0x18, 0x03, 0x04, 0x04, 0x03, / / 0x05 continu DC
0x08, 0x14, 0x1c, 0x14, 0x03, 0x04, 0x04, 0x03, / / 0x06 alternatif ac
0x04, 0x04, 0x0e, 0x0a, 0x0a, 0x0e, 0x04, 0x04, / / 0x07 resistance
0x00 / / fin
};
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / parametres de reglage du debit du port serie
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / (BRGH = 1) SPBRG = fosc / (16 * baudrate) - 1
Const char debitspbrg[] =
/ / { 103, 51, 16, 8, 0}; / / 16mhz
/ / { 155, 77, 25, 12}; / / 24mhz
{ 47, 23, 7, 3}; / / 7.3728mhz
/ / 9600 19200 57600 115200
#Define debitinit 3 / / 115kbps
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / variables main + isr
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#Define tmr1_set 0b00110000 / / prescaler 1: 8, osc off, fosc / 4, stop timer1
#Define tmr1_set1 0b00000000 / / prec 1: 1, osc off, fosc / 4, stop tmr1
#Define intcon_set 0b01000000 / / GIE = 0, pie unmasked
#Define option_set 0b10101000 / / prescaler 1: 1 sur RA4
unsigned char tmr1h2; / / timer High nb2 - > compteur 16777216
/ / unsigned char hh = 0, mm = 0, ss = 0; / / horloge
bank1 volatile char bufferrx[80]; / / tampon de reception rs232
#Define sizeofbufferrx 80
unsigned char indexrx = 0; / / index de position dans bufferrx
unsigned char carrx = 0; / / dernier caractere recu
static Bit bufferrxovf; / / '1' si overflow bufferRX
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / initialise le timer 1 pour des temporisations
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / temporisation 16 bits tmr1h2 - TMR1H
/ / horloge: 24mhz = > 0.166us soit 6.000.000 * 0.166us = 1s
/ / = = > timer1: prescale 1: 8 = > 6.000.000 / 8 = 750.000
/ / = = > tmr1h2 = > 15 * 50.000 = 750.000
/ / 65536 - 50000 = 0x3cb0
void
init_tmr1() {
tmr1h2 = 256 - 15;
TMR1IF = 0;
TMR1H = 0x3c;
TMR1L = 0xb0;
T1CON = tmr1_set; / / 0b00110000 = prescaler 1: 8, osc off, fosc / 4, stop timer1
TMR1ON = 1;
/ / activer PIE1 + GIE dans INTCON, TMR1IE dans PIE1,
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / interruptions
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
static void Interrupt
isr(void) {
If(TMR1IF) { / / horloge(duree de fonctionnement)
TMR1H = 0x3c;
TMR1L = 0xb0;
tmr1h2 + + ;
If(tmr1h2 = = 0) {
tmr1h2 = 256 - 15;
/ / led1 = !led1;
}
TMR1IF = 0; / / efface le flag isr
}
/ * If(T0IF) {
/ / TMR0 = tmr0_set; efface le compteur
/ / tmr0high + + ;
T0IF = 0; / / efface le flag isr
} * /
If(RCIF) { / / reception rs232 = > bufferrx
If(OERR = = 1) { / / overrun error
CREN = 0;
CREN = 1;
carrx = rcreg;
}
carrx = rcreg;
bufferrx[indexrx] = carrx;
indexrx + + ;
If(indexrx >= sizeofbufferrx) {
indexrx = 0;
bufferrxovf = 1;
}
/ / bootloader
If(bufferrx[0] = = 'A') {
RCIF = 0;
GIE = 0;
/ / tempo 1 / 15s = 65ms(configurer cd2m avec 10 try a 65ms)
TMR1H = 0x3c;
TMR1L = 0xb0;
led1 = 1;
led2 = 1;
While(!tmr1if) ;
led1 = 0;
led2 = 0;
asm("ljmp 0x0000") ; / / = = > bootloader(reset)
}
led2 = !led2;
/ / echo caractere recu
While(TRMT = = 0) ; / / attendre que le tampon soit vide
TXREG = carrx; / / emet le caractere echo
RCIF = 0; / / reset flag isr
}
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / initialisation des parametres
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
init_system(void) {
/ / = = = = = = = = = = = = = = = initialisation des ports i / o = = = = = = = = = = = = =
PORTA = 0; / / sorties PORTA a 0
PORTB = 0; / / sorties PORTB a 0
/ / PORTC = 0; / / sorties PORTC a 0
PORTC & = 0xc0; / / sorties PORTC a 0 sauf RC6 / 7
PORTD = 0; / / sorties PORTD a 0
PORTE = 0; / / sorties PORTE a 0
/ / ADCON0 = 0xc5;
ADCON0 = 0x85; / / 0b10000101(fosc / 32, RA0, GO, 0, a / D On)
/ / ADCON1 = 0x0e; / / 0b00001110(left justify(8bits), RA0 ana)
ADCON1 = 0b10000010; / / (right justify(10bits), RA0 - 5 ana)
TRISA = trisaconf; / / '1' entree ; '0' sortie
TRISB = trisbconf; / / '1' entree ; '0' sortie
TRISC = triscconf; / / '1' entree ; '0' sortie
TRISD = trisdconf; / / '1' entree ; '0' sortie
TRISE = triseconf; / / '1' entree ; '0' sortie
/ / #Define option_set 0b10101000 / / prescaler 1: 1 sur RA4
option = 0b00000000; / / charge masque registre option = > pull - up On RB
/ / = = = = = = = = = configuration des interruptions = = = = = = = = = = / /
PIE1 = 0b00100001; / / RCIE(usart rx) + timer1
PIE2 = 0b00000000;
RCIF = 0;
INTCON = 0b01000000; / / masque interruption, GIE + pie
/ / = = = = = = = = = initialisation des peripheriques = = = = = = = = = / /
bobi = 1; / / bobine off
cmd_samp = 1; / / 4066 off
init232(debitspbrg[debitinit]) ; / / port serie, 115kbds, pas de parite, 8bits, 1 stop
/ / / / tempo(3) ; / / tempo 0.5ms
init_tmr1() ;
lcd_init() ; / / init lcd 4 bits
lcd_putcmd(0x40) ; / / chargement des caracteres redefinis
lcd_puts(cg_ram) ; / / en cgram
lcd_clear() ; / / efface le lcd(added by cgram)
GIE = 1; / / interruptions On
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / initialisation affichage introduction
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
init_intro(void) {
unsigned char cpt;
version() ; / / tx232_puts: version1, version2
tx232( '>'); // prompt
/ / / lcd_bitmap(bmp0) ; / / seb scope
/ / tempo_x65ms(50) ;
lcd_putcmd(disp_on) ;
lcd_clear() ;
lcd_putchar(0x00) ;
/ / 12345678901234567890
lcd_puts("PI metal Detect SJ\x01\x02") ;
tempo_x65ms(18) ;
lcd_clear() ;
lcd_puts("by Seb 02-13(c)2005") ;
tempo_x65ms(15) ;
lcd_clear() ;
/ / test 12v ######
/ / 12345678901234567890
lcd_puts(" Battery Test !!") ;
For(cpt = 8; cpt > 0; cpt - -) {
lcd_putcmd(disp_off) ;
tempo_x65ms(3) ;
lcd_putcmd(disp_on) ;
/ / beepxkhz(0) ;
tempo_x65ms(5) ;
}
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / detection bootloader
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ * test_loader() {
If(RCIF) {
If(rx232() = = 'A') {
lcd_off() ;
asm("ljmp 0x0000") ; / / reset
}
}
} * /
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / info de version rs232
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
version(void) {
tx232_puts(version1) ;
tx232_puts(version2) ;
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / decodage commande rs232
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / main
/ / reglage r12(pot droit): ajuster pour avoir pb = 500
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#Define nbmenu 5
void
main(void) {
unsigned char i = 0, fpwm = 255, / / 255 = > 450hz
menu = 0;
/ / 165, 165, 45, 4
/ / 148, 78, 133, 31
/ / 150, 78, 33, 35 / / transfo
/ / 188, 78, 33, 135 / / bat
/ / 138, 78, 33, 135
/ / 120, 67, 38, 216 bob2 transfo
unsigned char m_pulse = 154, / / duree de l 'impulsion (us)
m_wait = 35, / / pause apres impulsion(us)
m_samp = 40, / / acquisition(4066)(us)
m_wait_short = 240, / / pause apres acquisition(us)
m_wait_long = 45; / / 35 / / 4; / / pause entre 2 pulses(ms)
/ / us * 0.855us = > vrai us
unsigned int ana_out, / / signal detection metal 2
ana_pb, / / filtre passe - bas
ana_samp, / / signal detection metal 1
ana_12v, / / surveillance + 9v(batterie)
ana_15v, / / surveillance + 15v(icl7660)
tmpint, / / pour moyenne ana
zero_out, / / zero ana_out
zero_pb; / / zero ana_pb
/ / configurations des entrees / sorties
/ * SPBRG = 0x00; / / #corrige bug bootload
TXSTA = 0x02;
RCSTA = 0x00; * /
init_system() ;
/ / affichage de l 'INTRODUCTION
init_intro() ;
lcd_clear() ;
init_pwm() ;
For(;
{
If(bufferrxovf = = 1) {
bufferrxovf = 0;
tx232_puts("\n\rBuffer Overflow !\n\r>") ;
}
If((carrx = = '\n')||(carRX=='\r')) {
parse232() ;
}
/ / 10khz
ana_out = 0;
ana_pb = 0;
ana_samp = 0;
GIE = 0;
/ / faire 5 pulses de stabilisation
For(i = 64 + 5; i! = 0; i - -) { / / 32
bobi = 0; / / bobine On
delayus(m_pulse) ;
bobi = 1; / / bobine off
delayus(m_wait) ;
cmd_samp = 0; / / 4066 On
delayus(m_samp) ;
/ / conversions analogique 10bits.. .
adc_read(ana_out, &tmpint) ; / / signal detection metal 2
If(i <= 64) ana_out + = tmpint;
adc_read(ana_pb, &tmpint) ; / / filtre passe - bas
If(i <= 64) ana_pb + = tmpint;
adc_read(ana_samp, &tmpint) ; / / signal detection metal 1
If(i <= 64) ana_samp + = tmpint;
cmd_samp = 1;
delayus(m_wait_short) ;
}
GIE = 1;
/ / duree = ((m_pulse + m_wait + m_samp + m_wait_short) *.855us + 5us * 3) * 64
/ / duree = [17300us;56000us]
/ / ana(1ch) = 32 / 7.3728e6
ana_samp = ana_samp > > 6; / / div 64 / / 32 > > 5
ana_out = ana_out > > 6; / / div 64 / / 32
ana_pb = ana_pb > > 6; / / div 64 / / 32
/ / affichage 10bits = > 2^10 = 1024 max
/ / 12345678901234567890
/ / o = xxxx S = xxxx ????
lcd_goto(0x08) ; / / position 0(ligne 1)
lcd_puts("O=") ;
lcd_uint(ana_out, 2) ;
lcd_puts(" P=") ;
lcd_line2() ; / / revised
lcd_puts("=") ; / / inutile: transitions trop rapide(revised)
lcd_uint(ana_pb, 9) ;
switch(menu) {
case 0: / / m_pulse
lcd_puts(" pu=") ;
lcd_uchar(m_pulse, 17) ;
break;
case 1: / / m_wait
lcd_puts(" wa=") ;
lcd_uchar(m_wait, 17) ;
break;
case 2: / / m_samp
lcd_puts(" sa=") ;
lcd_uchar(m_samp, 17) ;
break;
case 3: / / m_wait_short
lcd_puts(" ws=") ;
lcd_uchar(m_wait_short, 17) ;
break;
case 4: / / m_wait_long
lcd_puts(" wl=") ;
lcd_uchar(m_wait_long, 17) ;
break;
case 5: / / zero_out - ana_out
lcd_puts(" D=") ;
lcd_uint(fpwm, 16) ;
break;
}
/ / fpwm = 115200 / (PR2 + 1) = > [450hz - 115khz]
/ / fpwm = ana_samp > > 2;
If(ana_out >= zero_out + 2) { / / ana_out - zero_out > 2 / / 3
fpwm = 70 + (((zero_out - ana_out) > > 0) < < 1) ; / / > > 1 < < 2 / / 100 + / / (((ana_pb - zero_pb) > > 3) < < 2) ;
}
Else {
fpwm = 0;
}
update_pwm(fpwm) ;
/ / conversion ana 12v 15v
adc_read(ana_15v, &ana_15v) ; / / surveillance + 15v(icl7660)
adc_read(ana_12v, &ana_12v) ; / / surveillance + 9v(batterie)
If(!bp_up) {
/ / fpwm + + ;
/ / m_pulse + + ;
/ / While(!bp_up) ;
switch(menu) {
case 0: m_pulse + + ;
break;
case 1: m_wait + + ;
break;
case 2: m_samp + + ;
break;
case 3: m_wait_short + + ;
break;
case 4: m_wait_long + + ;
break;
}
}
If(!bp_down) {
/ / fpwm - -;
/ / m_pulse - -;
/ / While(!bp_down) ;
switch(menu) {
case 0: m_pulse - -;
break;
case 1: m_wait - -;
break;
case 2: m_samp - -;
break;
case 3: m_wait_short - -;
break;
case 4: m_wait_long - -;
break;
}
}
If(!bp_enter) {
/ / lcd_puts("bp ENTER") ;
/ / tx232_puts("test BP ENTER\n\r") ;
menu + + ;
If(menu > nbmenu) menu = 0;
While(!bp_enter) ;
}
If(!bp_esc) {
menu - -;
If(menu = = 255) menu = nbmenu;
While(!bp_esc) ;
}
If(!bp_zero) {
/ / 12345678901234567890
/ / 12v = xxxx 15v = xxxx ????
zero_out = ana_out;
zero_pb = ana_pb;
lcd_clear() ;
lcd_puts("12V=") ;
lcd_uint(ana_12v, 4) ;
lcd_puts(" *15V=") ;
lcd_uint(ana_15v, 14) ;
/ * lcd_puts(" O=") ; / / valeur zero_out
lcd_uint(zero_out, ??) ; * /
While(!bp_zero) ;
lcd_clear() ;
}
/ / While((bp_port & bp_mask) ! = bp_mask) ; / / antirebond
/ / test bp puis timeout timer0 / 1 / 2??
delayms(m_wait_long) ; / / ??
} / / fin du For(;
}
/ / eof / /
lcd.c
//========================================================================================
// NOM: lcd.c
// Date: 02/08/2004
// Version: 1.00
// Circuit: circuit final PI detect
// Auteur: SJ
// Micro: PIC16F877 7.3728MHz -> tcycl = 0.5425us
// Revision: correction rw_start_eeprom
//========================================================================================
#include "lcd.h"
/*static bit tmpGIE; // flag pour GIE
#define FLAG_GIE_SAVE tmpGIE = 0;if (GIE) tmpGIE = 1;GIE = 0;
#define FLAG_GIE_REST if (tmpGIE) GIE = 1;*/
// SAVE+REST = 7 ROM
//volatile unsigned char touche;
// AFFICHEUR LCD
#define LCD_INIT_VALUE 0x30
// TEMPO
#define FREQ_MULT (FOSC)/(4000000L)
//========================================================================================
// Temporisation pour le LCD
//========================================================================================
// x * 1us ( DelayUs(200) = 170.9us)
void
DelayUs(unsigned char x) {
unsigned char tmp;
for(tmp = x>>1; tmp!=0; tmp--) {
}
}
void
DelayMs(unsigned char cnt)
{
unsigned char i;
while (cnt--) {
for (i=5 ;i!=0 ;i--) {
DelayUs(234); // Adjuster pour 200us
}
}
}
//========================================================================================
void
tempo_x65ms(unsigned char nbr){
while(nbr--) {
DelayMs(65);
}
}
//========================================================================================
// LCD HD44780 4 bits MSB sur PORTD
// initialisation du LCD
//========================================================================================
void
lcd_init(void)
{
LCD_RS = 0;
LCD_DATA = 0;
LCD_EN = 0;
DelayMs(15);
LCD_DATA = LCD_INIT_VALUE;
LCD_STROBE();
DelayMs(5);
LCD_DATA = LCD_INIT_VALUE;
LCD_STROBE();
DelayUs(200);
LCD_DATA = LCD_INIT_VALUE;
LCD_STROBE();
DelayMs(5); //#TEMPO
LCD_DATA = 0x20; // Set 4-bit mode
LCD_STROBE();
lcd_putcmd(0x28); // Function Set
lcd_putcmd(0x01); //Display Clear *1
lcd_putcmd(0x0C); //Display On
lcd_putcmd(0x06); //Entry Mode
lcd_putcmd(0x0C); //Disp On
/*lcd_putcmd(CLR_DISP); // clr Home
lcd_putcmd(DISP_ON); // display on clign off
lcd_putcmd(ENTRY_INC); // pas de decalage
lcd_putcmd(DISP_ON); // display on*/
DelayMs(25); // ajout sinon PB cgRam
}
//========================================================================================
// Lecture LCD (sans attente)
//========================================================================================
unsigned char
lcd_read_cmd_nowait(void)
{
unsigned char c, readc;
LCD_TRIS = LCD_TRIS_IN;
LCD_RW = 1; // Read LCD
asm("nop"); // short propagation delay
asm("nop"); // short propagation delay
LCD_STROBE_READ(readc); // Read high nibble
// Move 4 bits to high nibble while zeroing low nibble
c = ( ( readc << 4 ) & 0xF0 );
LCD_STROBE_READ(readc); // Read low nibble
c |= readc & 0x0F ; // Or in 4 more bits to low nibble
LCD_RW = 0; // Return to default mode of writing LCD
LCD_TRIS = LCD_TRIS_OUT; // Return to default mode of writing LCD
return(c);
}
//========================================================================================
// Check Busy : Boucle tant que le LCD n'est pas pret (ou timeout)
//========================================================================================
void
lcd_check_busy(void)
{
// To avoid hanging forever in event there's a bad or
// missing LCD on hardware. Will just run SLOW, but still run.
unsigned char retry;
unsigned char c;
for (retry=255; retry!=0; retry--) {
c = lcd_read_cmd_nowait();
if ((c&0x80)==0x00) break; // Check busy bit. If zero, no longer busy
}
}
//========================================================================================
// ecrit une commande sur le LCD
//========================================================================================
void
lcd_putcmd(unsigned char c)
{
//DelayMs(5); //#TEMPO AJUSTER
DelayUs(10);
//lcd_check_busy();
LCD_RS = 0;
LCD_DATA &= 0x0F;
LCD_DATA |= (c & 0xF0);
LCD_STROBE();
LCD_DATA &= 0x0F;
LCD_DATA |= (c << 4);
LCD_STROBE();
}
//========================================================================================
// ecrit un caractère sur le LCD
//========================================================================================
lcd_putchar(unsigned char c){
//DelayMs(5); //#TEMPO AJUSTER
DelayUs(10);
//lcd_check_busy();
LCD_RS = 1;
LCD_DATA &= 0x0F;
LCD_DATA |= (c & 0xF0);
LCD_STROBE();
LCD_DATA &= 0x0F;
LCD_DATA |= (c << 4);
LCD_STROBE();
LCD_RS = 0;
}
//========================================================================================
// ecrit une string de caracteres sur le LCD
//========================================================================================
lcd_puts(const char * s){
while(*s) lcd_putchar(*s++);
}
//========================================================================================
// Clear and home the LCD
//========================================================================================
void
lcd_clear(void){
lcd_putcmd(0x01);
DelayMs(10); // 2ms
}
//========================================================================================
// convertit un nombre hexadecimal en ascii
//========================================================================================
unsigned char
hexa2ascii(unsigned char tmp){
tmp += 0x30;
if (tmp>0x39) tmp+=7;
return tmp;
}
//========================================================================================
// convertit un nombre ascii en hexa
//========================================================================================
unsigned char
ascii2hexa(unsigned char tmp){
tmp -= 0x30;
if (tmp>0x09) tmp-=7;
return tmp;
}
//========================================================================================
// ecrit un nombre en hexa sur le LCD
//========================================================================================
lcd_hexa(unsigned char c){
lcd_putchar( hexa2ascii(c >> 4) );
lcd_putchar( hexa2ascii(c & 0x0F) );
}
//========================================================================================
// ecrit un espace a la place d'un '0'
//========================================================================================
void
lcd_putchar_0(unsigned char car, unsigned char* zero){
unsigned char tmp;
if ((car=='0')&&(*zero==0)) tmp = ' ';
else {
tmp = car;
(*zero)++;
}
lcd_putchar(tmp);
}
//========================================================================================
// ecrit un unsigned char sur le LCD
//========================================================================================
void
lcd_uchar(unsigned char u, unsigned char pos){
unsigned char Dtemp, zero=0;
lcd_goto(pos);
lcd_putchar_0(u/100+0x30, &zero); // cent (elimine '0' non significatif)
Dtemp = u%100;
lcd_putchar_0(Dtemp/10+0x30, &zero); // dix
lcd_putchar(Dtemp%10+0x30); // unite
}
//========================================================================================
// ecrit un unsigned int sur le LCD
//========================================================================================
void
lcd_uint(unsigned int u, unsigned char pos){
unsigned char zero=0;
unsigned int Dtemp;
lcd_goto(pos);
lcd_putchar_0(u/1000+0x30, &zero); // mille (elimine '0' non significatif)
Dtemp = u%1000;
lcd_putchar_0(Dtemp/100+0x30, &zero); // cent
Dtemp = u%100;
lcd_putchar_0(Dtemp/10+0x30, &zero); // dix
lcd_putchar(Dtemp%10+0x30); // unite
}
//========================================================================================
// Entree analogique Mode 8 bits (justify)
// Renvoie la tension d'alim 12V
//========================================================================================
unsigned char
ana12(void){
unsigned char volt;
ADGO = 1;
while(ADGO);
volt = ADRESH + (ADRESH>>3); // volt = ADRESH*(1+1/8)
return volt;
}
//========================================================================================
// Valeur ANA Mode 10bits
//========================================================================================
void
adc_read(unsigned char channel, unsigned int* val)
{
//0xC1; // enable ADC, RC osc.
ADCON0 = (channel << 3) + 0x81; // => Fosc/32, enable ADC
ADGO = 1;
while(ADGO); // wait for conversion complete
*val = (unsigned int)(ADRESH<<8) + ADRESL;
}
//========================================================================================
// Sortie PWM pour buzzer
// Timer 2 presc : 1:16
// => PR2=0 => 115KHz, 12=> 8.8KHz, 64=> 1700Hz, 255=> 450Hz
//========================================================================================
void
init_pwm(void) {
// *** INITIALISATION MODULE PWM ***
// (1) Initialisation de la periode PWM (PR2 register).
// PWM period = [(PR2) + 1] ? 4 ? TOSC ? (TMR2 prescale value)
// >>TOSC = 1/7.3728MHz = 0.136 us
PR2 = 64; // 64 -> 30.769KHz
// (2) Initialisation du rapport cyclique PWM (CCPR1L register & CCP1CON<5:4> bits).
// PWM duty cycle = (CCPR1L:CCP1CON<5:4>) Tosc ? (TMR2 prescale value)
//CCPR1L = 0; // duty = 0% ; CCPR1L = 64 -> 100%
CCPR1L = PR2 >> 2; // duty = 50%
CCP1CON = 0x00; // PWM off + LSB = 0x0
// (3) broche CCP1 en sortie (TRISB<3> bit = 0).
// OK
// (4) Initialisation du prescaler et activation du TMR2 (T2CON).
//T2CON = 0b00000100; // post 1:1, T2 on, pre 1:1
//T2CON = 0b01111100; // post1:16?, T2 on, pre 1:1
T2CON = 0b00000110; // post1:1, T2 on, pre 1:16
// (5) Activation du module PWM.
CCP1CON = 0b00001100; // PWM on + LSB = 0x0
}
//========================================================================================
// Mise a jour PWM (nouvelle frequence duty 50%)
// FPWM = 1 / ((PR2+1)*4*TOSC*TMR2presc) avec TOSC = 0.136us, TMR2presc = 16
// = 115200 / (PR2+1) => [450Hz - 115KHz]
//========================================================================================
void
update_pwm(unsigned char val) {
PR2 = val;
CCPR1L = val >> 2;
}
//========================================================================================
// Port Serie RS232 8bits, no parity, 1 bit de stop
//========================================================================================
init232(char debit){
// Baud Rate = Fosc/(16(SPBRG+1))
SPBRG = debit;
// 103 : 9600bds, 51 : 19200bds, 16 : 57600bds, 8: 115kbds, 255 : 1Mbps!!! pour 16MHz
// 155 : 9600bds, 77 : 19200bds, 25 : 57600bds, 12 : 115kbds pour 24MHz
TXSTA = 0b00100100;//0b10100100; // Asynchronous, 8bits, TXEN, Asynchronous, High speed
RCSTA = 0b10010000; // SPEN : enable port, CREN : reception continue
//rx232(); // correction bug bootloader (sinon port bloque ?)
/* SPBRG = DIVIDER;
TXSTA = (SPEED|NINE_BITS|0x20);
RCSTA = (NINE_BITS|0x90);*/
/*TRISC6=OUTPUT;
TRISC7=INPUT;
rx232();*/
}
tx232(char val){
while(TRMT==0); // attendre que le tampon soit vide
TXREG = val; // emet le caractere
}
char
rx232(void){
unsigned char tmp; // #### UTILE ??? cf doc MidRange
if (OERR==1) { //overrun Error
CREN = 0;
CREN = 1;
tmp = RCREG;
}
RCIF = 0; // reset flag ISR
return RCREG; // retourne le caractere recu
}
// ecrit une string de caracteres sur le port serie
tx232_puts(const char * s){
while(*s)
tx232(*s++);
}
/*// detection de reception
char
rx232_detc(void){
while(!RCIF);
return rx232();
}*/
// ecrit 2 caracteres ascii
tx232_2ascii(unsigned char car){
tx232(hexa2ascii(car >> 4));
tx232(hexa2ascii(car & 0x0F));
}
//========================================================================================
// LECTURE d'un octet dans l'EEPROM
//========================================================================================
unsigned char
readEE(unsigned char adr){
//return EEPROM_READ(adr); // bug -W-3 no effect !!
EEADR = adr; // selectionne la bonne adresse
EEPGD = 0; // memoire donnees
RD = 1; // commence la lecture
return EEDATA; // renvoie l'octet lu-
}
//========================================================================================
// ECRITURE d'un octet dans l'EEPROM
//========================================================================================
writeEE(unsigned char adr, unsigned char data){
//EEPROM_WRITE(adr, data); // avec blocage ISR + remise en route ISR
/*//char tmp;
if (GIE==1) CARRY = 1; // tmp = 1;
else CARRY = 0; // tmp = 0;
while (WR==1); // attend la fin de l'ecriture precedante
EEADR = adr; // selectionne la bonne adresse
EEDATA = data; // donnee a ecrire
EEPGD = 0; // memoire donnees
WREN = 1; // autorise l'ecriture
GIE = 0; // desactive les ISR si activees
EECON2 = 0x55; // nombres magiques
EECON2 = 0xAA; //
WR = 1; // commence l'ecriture
GIE = CARRY; //(bit)tmp; // reactive les interruptions
WREN = 0; // interdit l'ecriture
*/
// HI-TECH macro + Microchip P43 ex4-2
while(WR)continue; // attends la fin de l'ecriture precedante
EEADR=adr; // selectionne la bonne adresse
EEDATA=data; // donnee a ecrire
EEPGD=0; // memoire donnees
WREN=1; // autorise l'ecriture
CARRY=0; // sauvegarde & desactive GIE
if(GIE) CARRY=1;
GIE=0; // desactive les ISR si activees
EECON2=0x55; // nombres magiques
EECON2=0xAA;
WR=1; // commence l'ecriture
if(CARRY) GIE=1; // reactive les interruptions
WREN=0; // interdit l'ecriture
}
/*
// ajoute 37 octets ROM // A TESTER
//========================================================================================
// STOCKAGE variables RAM persistant
//========================================================================================
// LECTURE d'une suite d'octet dans l'EEPROM : ZONE PERSISTANTE
// appel : read_from_eeprom(_Lnvram, _Hnvram-_Lnvram);
//========================================================================================
read_from_eeprom(char * start, unsigned char length){
unsigned char i;
for(i=0; i<length; i++){
*start = readEE(i);
start++;
}
}
//========================================================================================
// ECRITURE d'une suite d'octet dans l'EEPROM : ZONE PERSISTANTE
// appel : write_to_eeprom(_Lnvram, _Hnvram-_Lnvram);
//========================================================================================
write_to_eeprom(char * start, unsigned char length){
unsigned char i;
for(i=0; i<length; i++){
writeEE(i, *start);
start++;
}
}*/
//EOF//
i build project using 16f877 and seiko lcd (l167100j00) 1x16 char.
i try long hard but only get 8 digits to display. i sur it only minor problem for someone knowing more than me. hoping to get answer.
my grateful for help. sorry bad english,hope you able understand.
seb
metal.c
/ / nom: metal.C
/ / date: 07 / 08 / 2004
/ / version: 1.00
/ / circuit: circuit final detecteur pi
/ / auteur: sj
/ / micro: pic16f877 7.3728mhz - > tcycl = 0.5425 us
/ / = = = = = = = = = = = = = = = = = = = = = = = = = =
#include "metal.h"
#include "lcd.h"
/ / #include "string.h"
/ / fusibles de configuration, eeprom interne(256 octets), n°identification
__config(wdtdis & hs & pwrten & unprotect & bordis & lvpdis & debugdis) ;
/ / eeprom interne: 256 octets max
/ / __eeprom_data(0, 1, 2, 3, 4, 5, 6, 7) ;
#Define version1 "* Seb PI Metal *\n\r"
#Define version2 "(c)by Seb 07-08-2004\n\r"
/ / __idloc(1234) ;
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / macro blocage interruptions
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ *
static Bit tmpgie2; / / flag pour GIE
#Define flag_gie_save2 tmpgie2 = 0;if(GIE) tmpgie2 = 1;gie = 0;
#Define flag_gie_rest2 If(tmpgie2) GIE = 1;
/ / Save + rest = 7 rom
* /
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / thus all the 'persistent' variables will be kept together, and you can
/ / get the bounds of this psect from the following declarations:
/ / pour stockage permanent en eeprom des variables utiliser:
/ / read_from_eeprom(_lnvram, _hnvram - _lnvram) ;
/ / write_to_eeprom(_lnvram, _hnvram - _lnvram) ;
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
extern char _lnvram[], _hnvram[];
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / essayer de passer sur 7bits!!!!
/ / * definition des 8 caracteres en cg - ram * / /
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Const char cg_ram[] =
{0x0e, 0x11, 0x0e, 0x14, 0x0f, 0x04, 0x1a, 0x02, / / 0x00 bon.gauche
0x0e, 0x11, 0x0e, 0x05, 0x1e, 0x04, 0x0b, 0x08, / / 0x01 bon.droit
0x0e, 0x11, 0x0e, 0x04, 0x1f, 0x04, 0x0a, 0x11, / / 0x02 bon.milieu
0x20, 0x20, 0x15, 0x20, 0x1f, 0x20, 0x20, 0x20, / / 0x03 continu =
0x20, 0x0a, 0x15, 0x20, 0x1f, 0x20, 0x20, 0x20, / / 0x04 alternatif ~_
0x18, 0x14, 0x14, 0x18, 0x03, 0x04, 0x04, 0x03, / / 0x05 continu DC
0x08, 0x14, 0x1c, 0x14, 0x03, 0x04, 0x04, 0x03, / / 0x06 alternatif ac
0x04, 0x04, 0x0e, 0x0a, 0x0a, 0x0e, 0x04, 0x04, / / 0x07 resistance
0x00 / / fin
};
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / parametres de reglage du debit du port serie
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / (BRGH = 1) SPBRG = fosc / (16 * baudrate) - 1
Const char debitspbrg[] =
/ / { 103, 51, 16, 8, 0}; / / 16mhz
/ / { 155, 77, 25, 12}; / / 24mhz
{ 47, 23, 7, 3}; / / 7.3728mhz
/ / 9600 19200 57600 115200
#Define debitinit 3 / / 115kbps
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / variables main + isr
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#Define tmr1_set 0b00110000 / / prescaler 1: 8, osc off, fosc / 4, stop timer1
#Define tmr1_set1 0b00000000 / / prec 1: 1, osc off, fosc / 4, stop tmr1
#Define intcon_set 0b01000000 / / GIE = 0, pie unmasked
#Define option_set 0b10101000 / / prescaler 1: 1 sur RA4
unsigned char tmr1h2; / / timer High nb2 - > compteur 16777216
/ / unsigned char hh = 0, mm = 0, ss = 0; / / horloge
bank1 volatile char bufferrx[80]; / / tampon de reception rs232
#Define sizeofbufferrx 80
unsigned char indexrx = 0; / / index de position dans bufferrx
unsigned char carrx = 0; / / dernier caractere recu
static Bit bufferrxovf; / / '1' si overflow bufferRX
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / initialise le timer 1 pour des temporisations
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / temporisation 16 bits tmr1h2 - TMR1H
/ / horloge: 24mhz = > 0.166us soit 6.000.000 * 0.166us = 1s
/ / = = > timer1: prescale 1: 8 = > 6.000.000 / 8 = 750.000
/ / = = > tmr1h2 = > 15 * 50.000 = 750.000
/ / 65536 - 50000 = 0x3cb0
void
init_tmr1() {
tmr1h2 = 256 - 15;
TMR1IF = 0;
TMR1H = 0x3c;
TMR1L = 0xb0;
T1CON = tmr1_set; / / 0b00110000 = prescaler 1: 8, osc off, fosc / 4, stop timer1
TMR1ON = 1;
/ / activer PIE1 + GIE dans INTCON, TMR1IE dans PIE1,
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / interruptions
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
static void Interrupt
isr(void) {
If(TMR1IF) { / / horloge(duree de fonctionnement)
TMR1H = 0x3c;
TMR1L = 0xb0;
tmr1h2 + + ;
If(tmr1h2 = = 0) {
tmr1h2 = 256 - 15;
/ / led1 = !led1;
}
TMR1IF = 0; / / efface le flag isr
}
/ * If(T0IF) {
/ / TMR0 = tmr0_set; efface le compteur
/ / tmr0high + + ;
T0IF = 0; / / efface le flag isr
} * /
If(RCIF) { / / reception rs232 = > bufferrx
If(OERR = = 1) { / / overrun error
CREN = 0;
CREN = 1;
carrx = rcreg;
}
carrx = rcreg;
bufferrx[indexrx] = carrx;
indexrx + + ;
If(indexrx >= sizeofbufferrx) {
indexrx = 0;
bufferrxovf = 1;
}
/ / bootloader
If(bufferrx[0] = = 'A') {
RCIF = 0;
GIE = 0;
/ / tempo 1 / 15s = 65ms(configurer cd2m avec 10 try a 65ms)
TMR1H = 0x3c;
TMR1L = 0xb0;
led1 = 1;
led2 = 1;
While(!tmr1if) ;
led1 = 0;
led2 = 0;
asm("ljmp 0x0000") ; / / = = > bootloader(reset)
}
led2 = !led2;
/ / echo caractere recu
While(TRMT = = 0) ; / / attendre que le tampon soit vide
TXREG = carrx; / / emet le caractere echo
RCIF = 0; / / reset flag isr
}
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / initialisation des parametres
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
init_system(void) {
/ / = = = = = = = = = = = = = = = initialisation des ports i / o = = = = = = = = = = = = =
PORTA = 0; / / sorties PORTA a 0
PORTB = 0; / / sorties PORTB a 0
/ / PORTC = 0; / / sorties PORTC a 0
PORTC & = 0xc0; / / sorties PORTC a 0 sauf RC6 / 7
PORTD = 0; / / sorties PORTD a 0
PORTE = 0; / / sorties PORTE a 0
/ / ADCON0 = 0xc5;
ADCON0 = 0x85; / / 0b10000101(fosc / 32, RA0, GO, 0, a / D On)
/ / ADCON1 = 0x0e; / / 0b00001110(left justify(8bits), RA0 ana)
ADCON1 = 0b10000010; / / (right justify(10bits), RA0 - 5 ana)
TRISA = trisaconf; / / '1' entree ; '0' sortie
TRISB = trisbconf; / / '1' entree ; '0' sortie
TRISC = triscconf; / / '1' entree ; '0' sortie
TRISD = trisdconf; / / '1' entree ; '0' sortie
TRISE = triseconf; / / '1' entree ; '0' sortie
/ / #Define option_set 0b10101000 / / prescaler 1: 1 sur RA4
option = 0b00000000; / / charge masque registre option = > pull - up On RB
/ / = = = = = = = = = configuration des interruptions = = = = = = = = = = / /
PIE1 = 0b00100001; / / RCIE(usart rx) + timer1
PIE2 = 0b00000000;
RCIF = 0;
INTCON = 0b01000000; / / masque interruption, GIE + pie
/ / = = = = = = = = = initialisation des peripheriques = = = = = = = = = / /
bobi = 1; / / bobine off
cmd_samp = 1; / / 4066 off
init232(debitspbrg[debitinit]) ; / / port serie, 115kbds, pas de parite, 8bits, 1 stop
/ / / / tempo(3) ; / / tempo 0.5ms
init_tmr1() ;
lcd_init() ; / / init lcd 4 bits
lcd_putcmd(0x40) ; / / chargement des caracteres redefinis
lcd_puts(cg_ram) ; / / en cgram
lcd_clear() ; / / efface le lcd(added by cgram)
GIE = 1; / / interruptions On
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / initialisation affichage introduction
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
init_intro(void) {
unsigned char cpt;
version() ; / / tx232_puts: version1, version2
tx232( '>'); // prompt
/ / / lcd_bitmap(bmp0) ; / / seb scope
/ / tempo_x65ms(50) ;
lcd_putcmd(disp_on) ;
lcd_clear() ;
lcd_putchar(0x00) ;
/ / 12345678901234567890
lcd_puts("PI metal Detect SJ\x01\x02") ;
tempo_x65ms(18) ;
lcd_clear() ;
lcd_puts("by Seb 02-13(c)2005") ;
tempo_x65ms(15) ;
lcd_clear() ;
/ / test 12v ######
/ / 12345678901234567890
lcd_puts(" Battery Test !!") ;
For(cpt = 8; cpt > 0; cpt - -) {
lcd_putcmd(disp_off) ;
tempo_x65ms(3) ;
lcd_putcmd(disp_on) ;
/ / beepxkhz(0) ;
tempo_x65ms(5) ;
}
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / detection bootloader
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ * test_loader() {
If(RCIF) {
If(rx232() = = 'A') {
lcd_off() ;
asm("ljmp 0x0000") ; / / reset
}
}
} * /
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / info de version rs232
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
version(void) {
tx232_puts(version1) ;
tx232_puts(version2) ;
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / decodage commande rs232
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/ / main
/ / reglage r12(pot droit): ajuster pour avoir pb = 500
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#Define nbmenu 5
void
main(void) {
unsigned char i = 0, fpwm = 255, / / 255 = > 450hz
menu = 0;
/ / 165, 165, 45, 4
/ / 148, 78, 133, 31
/ / 150, 78, 33, 35 / / transfo
/ / 188, 78, 33, 135 / / bat
/ / 138, 78, 33, 135
/ / 120, 67, 38, 216 bob2 transfo
unsigned char m_pulse = 154, / / duree de l 'impulsion (us)
m_wait = 35, / / pause apres impulsion(us)
m_samp = 40, / / acquisition(4066)(us)
m_wait_short = 240, / / pause apres acquisition(us)
m_wait_long = 45; / / 35 / / 4; / / pause entre 2 pulses(ms)
/ / us * 0.855us = > vrai us
unsigned int ana_out, / / signal detection metal 2
ana_pb, / / filtre passe - bas
ana_samp, / / signal detection metal 1
ana_12v, / / surveillance + 9v(batterie)
ana_15v, / / surveillance + 15v(icl7660)
tmpint, / / pour moyenne ana
zero_out, / / zero ana_out
zero_pb; / / zero ana_pb
/ / configurations des entrees / sorties
/ * SPBRG = 0x00; / / #corrige bug bootload
TXSTA = 0x02;
RCSTA = 0x00; * /
init_system() ;
/ / affichage de l 'INTRODUCTION
init_intro() ;
lcd_clear() ;
init_pwm() ;
For(;
If(bufferrxovf = = 1) {
bufferrxovf = 0;
tx232_puts("\n\rBuffer Overflow !\n\r>") ;
}
If((carrx = = '\n')||(carRX=='\r')) {
parse232() ;
}
/ / 10khz
ana_out = 0;
ana_pb = 0;
ana_samp = 0;
GIE = 0;
/ / faire 5 pulses de stabilisation
For(i = 64 + 5; i! = 0; i - -) { / / 32
bobi = 0; / / bobine On
delayus(m_pulse) ;
bobi = 1; / / bobine off
delayus(m_wait) ;
cmd_samp = 0; / / 4066 On
delayus(m_samp) ;
/ / conversions analogique 10bits.. .
adc_read(ana_out, &tmpint) ; / / signal detection metal 2
If(i <= 64) ana_out + = tmpint;
adc_read(ana_pb, &tmpint) ; / / filtre passe - bas
If(i <= 64) ana_pb + = tmpint;
adc_read(ana_samp, &tmpint) ; / / signal detection metal 1
If(i <= 64) ana_samp + = tmpint;
cmd_samp = 1;
delayus(m_wait_short) ;
}
GIE = 1;
/ / duree = ((m_pulse + m_wait + m_samp + m_wait_short) *.855us + 5us * 3) * 64
/ / duree = [17300us;56000us]
/ / ana(1ch) = 32 / 7.3728e6
ana_samp = ana_samp > > 6; / / div 64 / / 32 > > 5
ana_out = ana_out > > 6; / / div 64 / / 32
ana_pb = ana_pb > > 6; / / div 64 / / 32
/ / affichage 10bits = > 2^10 = 1024 max
/ / 12345678901234567890
/ / o = xxxx S = xxxx ????
lcd_goto(0x08) ; / / position 0(ligne 1)
lcd_puts("O=") ;
lcd_uint(ana_out, 2) ;
lcd_puts(" P=") ;
lcd_line2() ; / / revised
lcd_puts("=") ; / / inutile: transitions trop rapide(revised)
lcd_uint(ana_pb, 9) ;
switch(menu) {
case 0: / / m_pulse
lcd_puts(" pu=") ;
lcd_uchar(m_pulse, 17) ;
break;
case 1: / / m_wait
lcd_puts(" wa=") ;
lcd_uchar(m_wait, 17) ;
break;
case 2: / / m_samp
lcd_puts(" sa=") ;
lcd_uchar(m_samp, 17) ;
break;
case 3: / / m_wait_short
lcd_puts(" ws=") ;
lcd_uchar(m_wait_short, 17) ;
break;
case 4: / / m_wait_long
lcd_puts(" wl=") ;
lcd_uchar(m_wait_long, 17) ;
break;
case 5: / / zero_out - ana_out
lcd_puts(" D=") ;
lcd_uint(fpwm, 16) ;
break;
}
/ / fpwm = 115200 / (PR2 + 1) = > [450hz - 115khz]
/ / fpwm = ana_samp > > 2;
If(ana_out >= zero_out + 2) { / / ana_out - zero_out > 2 / / 3
fpwm = 70 + (((zero_out - ana_out) > > 0) < < 1) ; / / > > 1 < < 2 / / 100 + / / (((ana_pb - zero_pb) > > 3) < < 2) ;
}
Else {
fpwm = 0;
}
update_pwm(fpwm) ;
/ / conversion ana 12v 15v
adc_read(ana_15v, &ana_15v) ; / / surveillance + 15v(icl7660)
adc_read(ana_12v, &ana_12v) ; / / surveillance + 9v(batterie)
If(!bp_up) {
/ / fpwm + + ;
/ / m_pulse + + ;
/ / While(!bp_up) ;
switch(menu) {
case 0: m_pulse + + ;
break;
case 1: m_wait + + ;
break;
case 2: m_samp + + ;
break;
case 3: m_wait_short + + ;
break;
case 4: m_wait_long + + ;
break;
}
}
If(!bp_down) {
/ / fpwm - -;
/ / m_pulse - -;
/ / While(!bp_down) ;
switch(menu) {
case 0: m_pulse - -;
break;
case 1: m_wait - -;
break;
case 2: m_samp - -;
break;
case 3: m_wait_short - -;
break;
case 4: m_wait_long - -;
break;
}
}
If(!bp_enter) {
/ / lcd_puts("bp ENTER") ;
/ / tx232_puts("test BP ENTER\n\r") ;
menu + + ;
If(menu > nbmenu) menu = 0;
While(!bp_enter) ;
}
If(!bp_esc) {
menu - -;
If(menu = = 255) menu = nbmenu;
While(!bp_esc) ;
}
If(!bp_zero) {
/ / 12345678901234567890
/ / 12v = xxxx 15v = xxxx ????
zero_out = ana_out;
zero_pb = ana_pb;
lcd_clear() ;
lcd_puts("12V=") ;
lcd_uint(ana_12v, 4) ;
lcd_puts(" *15V=") ;
lcd_uint(ana_15v, 14) ;
/ * lcd_puts(" O=") ; / / valeur zero_out
lcd_uint(zero_out, ??) ; * /
While(!bp_zero) ;
lcd_clear() ;
}
/ / While((bp_port & bp_mask) ! = bp_mask) ; / / antirebond
/ / test bp puis timeout timer0 / 1 / 2??
delayms(m_wait_long) ; / / ??
} / / fin du For(;
}
/ / eof / /
lcd.c
//========================================================================================
// NOM: lcd.c
// Date: 02/08/2004
// Version: 1.00
// Circuit: circuit final PI detect
// Auteur: SJ
// Micro: PIC16F877 7.3728MHz -> tcycl = 0.5425us
// Revision: correction rw_start_eeprom
//========================================================================================
#include "lcd.h"
/*static bit tmpGIE; // flag pour GIE
#define FLAG_GIE_SAVE tmpGIE = 0;if (GIE) tmpGIE = 1;GIE = 0;
#define FLAG_GIE_REST if (tmpGIE) GIE = 1;*/
// SAVE+REST = 7 ROM
//volatile unsigned char touche;
// AFFICHEUR LCD
#define LCD_INIT_VALUE 0x30
// TEMPO
#define FREQ_MULT (FOSC)/(4000000L)
//========================================================================================
// Temporisation pour le LCD
//========================================================================================
// x * 1us ( DelayUs(200) = 170.9us)
void
DelayUs(unsigned char x) {
unsigned char tmp;
for(tmp = x>>1; tmp!=0; tmp--) {
}
}
void
DelayMs(unsigned char cnt)
{
unsigned char i;
while (cnt--) {
for (i=5 ;i!=0 ;i--) {
DelayUs(234); // Adjuster pour 200us
}
}
}
//========================================================================================
void
tempo_x65ms(unsigned char nbr){
while(nbr--) {
DelayMs(65);
}
}
//========================================================================================
// LCD HD44780 4 bits MSB sur PORTD
// initialisation du LCD
//========================================================================================
void
lcd_init(void)
{
LCD_RS = 0;
LCD_DATA = 0;
LCD_EN = 0;
DelayMs(15);
LCD_DATA = LCD_INIT_VALUE;
LCD_STROBE();
DelayMs(5);
LCD_DATA = LCD_INIT_VALUE;
LCD_STROBE();
DelayUs(200);
LCD_DATA = LCD_INIT_VALUE;
LCD_STROBE();
DelayMs(5); //#TEMPO
LCD_DATA = 0x20; // Set 4-bit mode
LCD_STROBE();
lcd_putcmd(0x28); // Function Set
lcd_putcmd(0x01); //Display Clear *1
lcd_putcmd(0x0C); //Display On
lcd_putcmd(0x06); //Entry Mode
lcd_putcmd(0x0C); //Disp On
/*lcd_putcmd(CLR_DISP); // clr Home
lcd_putcmd(DISP_ON); // display on clign off
lcd_putcmd(ENTRY_INC); // pas de decalage
lcd_putcmd(DISP_ON); // display on*/
DelayMs(25); // ajout sinon PB cgRam
}
//========================================================================================
// Lecture LCD (sans attente)
//========================================================================================
unsigned char
lcd_read_cmd_nowait(void)
{
unsigned char c, readc;
LCD_TRIS = LCD_TRIS_IN;
LCD_RW = 1; // Read LCD
asm("nop"); // short propagation delay
asm("nop"); // short propagation delay
LCD_STROBE_READ(readc); // Read high nibble
// Move 4 bits to high nibble while zeroing low nibble
c = ( ( readc << 4 ) & 0xF0 );
LCD_STROBE_READ(readc); // Read low nibble
c |= readc & 0x0F ; // Or in 4 more bits to low nibble
LCD_RW = 0; // Return to default mode of writing LCD
LCD_TRIS = LCD_TRIS_OUT; // Return to default mode of writing LCD
return(c);
}
//========================================================================================
// Check Busy : Boucle tant que le LCD n'est pas pret (ou timeout)
//========================================================================================
void
lcd_check_busy(void)
{
// To avoid hanging forever in event there's a bad or
// missing LCD on hardware. Will just run SLOW, but still run.
unsigned char retry;
unsigned char c;
for (retry=255; retry!=0; retry--) {
c = lcd_read_cmd_nowait();
if ((c&0x80)==0x00) break; // Check busy bit. If zero, no longer busy
}
}
//========================================================================================
// ecrit une commande sur le LCD
//========================================================================================
void
lcd_putcmd(unsigned char c)
{
//DelayMs(5); //#TEMPO AJUSTER
DelayUs(10);
//lcd_check_busy();
LCD_RS = 0;
LCD_DATA &= 0x0F;
LCD_DATA |= (c & 0xF0);
LCD_STROBE();
LCD_DATA &= 0x0F;
LCD_DATA |= (c << 4);
LCD_STROBE();
}
//========================================================================================
// ecrit un caractère sur le LCD
//========================================================================================
lcd_putchar(unsigned char c){
//DelayMs(5); //#TEMPO AJUSTER
DelayUs(10);
//lcd_check_busy();
LCD_RS = 1;
LCD_DATA &= 0x0F;
LCD_DATA |= (c & 0xF0);
LCD_STROBE();
LCD_DATA &= 0x0F;
LCD_DATA |= (c << 4);
LCD_STROBE();
LCD_RS = 0;
}
//========================================================================================
// ecrit une string de caracteres sur le LCD
//========================================================================================
lcd_puts(const char * s){
while(*s) lcd_putchar(*s++);
}
//========================================================================================
// Clear and home the LCD
//========================================================================================
void
lcd_clear(void){
lcd_putcmd(0x01);
DelayMs(10); // 2ms
}
//========================================================================================
// convertit un nombre hexadecimal en ascii
//========================================================================================
unsigned char
hexa2ascii(unsigned char tmp){
tmp += 0x30;
if (tmp>0x39) tmp+=7;
return tmp;
}
//========================================================================================
// convertit un nombre ascii en hexa
//========================================================================================
unsigned char
ascii2hexa(unsigned char tmp){
tmp -= 0x30;
if (tmp>0x09) tmp-=7;
return tmp;
}
//========================================================================================
// ecrit un nombre en hexa sur le LCD
//========================================================================================
lcd_hexa(unsigned char c){
lcd_putchar( hexa2ascii(c >> 4) );
lcd_putchar( hexa2ascii(c & 0x0F) );
}
//========================================================================================
// ecrit un espace a la place d'un '0'
//========================================================================================
void
lcd_putchar_0(unsigned char car, unsigned char* zero){
unsigned char tmp;
if ((car=='0')&&(*zero==0)) tmp = ' ';
else {
tmp = car;
(*zero)++;
}
lcd_putchar(tmp);
}
//========================================================================================
// ecrit un unsigned char sur le LCD
//========================================================================================
void
lcd_uchar(unsigned char u, unsigned char pos){
unsigned char Dtemp, zero=0;
lcd_goto(pos);
lcd_putchar_0(u/100+0x30, &zero); // cent (elimine '0' non significatif)
Dtemp = u%100;
lcd_putchar_0(Dtemp/10+0x30, &zero); // dix
lcd_putchar(Dtemp%10+0x30); // unite
}
//========================================================================================
// ecrit un unsigned int sur le LCD
//========================================================================================
void
lcd_uint(unsigned int u, unsigned char pos){
unsigned char zero=0;
unsigned int Dtemp;
lcd_goto(pos);
lcd_putchar_0(u/1000+0x30, &zero); // mille (elimine '0' non significatif)
Dtemp = u%1000;
lcd_putchar_0(Dtemp/100+0x30, &zero); // cent
Dtemp = u%100;
lcd_putchar_0(Dtemp/10+0x30, &zero); // dix
lcd_putchar(Dtemp%10+0x30); // unite
}
//========================================================================================
// Entree analogique Mode 8 bits (justify)
// Renvoie la tension d'alim 12V
//========================================================================================
unsigned char
ana12(void){
unsigned char volt;
ADGO = 1;
while(ADGO);
volt = ADRESH + (ADRESH>>3); // volt = ADRESH*(1+1/8)
return volt;
}
//========================================================================================
// Valeur ANA Mode 10bits
//========================================================================================
void
adc_read(unsigned char channel, unsigned int* val)
{
//0xC1; // enable ADC, RC osc.
ADCON0 = (channel << 3) + 0x81; // => Fosc/32, enable ADC
ADGO = 1;
while(ADGO); // wait for conversion complete
*val = (unsigned int)(ADRESH<<8) + ADRESL;
}
//========================================================================================
// Sortie PWM pour buzzer
// Timer 2 presc : 1:16
// => PR2=0 => 115KHz, 12=> 8.8KHz, 64=> 1700Hz, 255=> 450Hz
//========================================================================================
void
init_pwm(void) {
// *** INITIALISATION MODULE PWM ***
// (1) Initialisation de la periode PWM (PR2 register).
// PWM period = [(PR2) + 1] ? 4 ? TOSC ? (TMR2 prescale value)
// >>TOSC = 1/7.3728MHz = 0.136 us
PR2 = 64; // 64 -> 30.769KHz
// (2) Initialisation du rapport cyclique PWM (CCPR1L register & CCP1CON<5:4> bits).
// PWM duty cycle = (CCPR1L:CCP1CON<5:4>) Tosc ? (TMR2 prescale value)
//CCPR1L = 0; // duty = 0% ; CCPR1L = 64 -> 100%
CCPR1L = PR2 >> 2; // duty = 50%
CCP1CON = 0x00; // PWM off + LSB = 0x0
// (3) broche CCP1 en sortie (TRISB<3> bit = 0).
// OK
// (4) Initialisation du prescaler et activation du TMR2 (T2CON).
//T2CON = 0b00000100; // post 1:1, T2 on, pre 1:1
//T2CON = 0b01111100; // post1:16?, T2 on, pre 1:1
T2CON = 0b00000110; // post1:1, T2 on, pre 1:16
// (5) Activation du module PWM.
CCP1CON = 0b00001100; // PWM on + LSB = 0x0
}
//========================================================================================
// Mise a jour PWM (nouvelle frequence duty 50%)
// FPWM = 1 / ((PR2+1)*4*TOSC*TMR2presc) avec TOSC = 0.136us, TMR2presc = 16
// = 115200 / (PR2+1) => [450Hz - 115KHz]
//========================================================================================
void
update_pwm(unsigned char val) {
PR2 = val;
CCPR1L = val >> 2;
}
//========================================================================================
// Port Serie RS232 8bits, no parity, 1 bit de stop
//========================================================================================
init232(char debit){
// Baud Rate = Fosc/(16(SPBRG+1))
SPBRG = debit;
// 103 : 9600bds, 51 : 19200bds, 16 : 57600bds, 8: 115kbds, 255 : 1Mbps!!! pour 16MHz
// 155 : 9600bds, 77 : 19200bds, 25 : 57600bds, 12 : 115kbds pour 24MHz
TXSTA = 0b00100100;//0b10100100; // Asynchronous, 8bits, TXEN, Asynchronous, High speed
RCSTA = 0b10010000; // SPEN : enable port, CREN : reception continue
//rx232(); // correction bug bootloader (sinon port bloque ?)
/* SPBRG = DIVIDER;
TXSTA = (SPEED|NINE_BITS|0x20);
RCSTA = (NINE_BITS|0x90);*/
/*TRISC6=OUTPUT;
TRISC7=INPUT;
rx232();*/
}
tx232(char val){
while(TRMT==0); // attendre que le tampon soit vide
TXREG = val; // emet le caractere
}
char
rx232(void){
unsigned char tmp; // #### UTILE ??? cf doc MidRange
if (OERR==1) { //overrun Error
CREN = 0;
CREN = 1;
tmp = RCREG;
}
RCIF = 0; // reset flag ISR
return RCREG; // retourne le caractere recu
}
// ecrit une string de caracteres sur le port serie
tx232_puts(const char * s){
while(*s)
tx232(*s++);
}
/*// detection de reception
char
rx232_detc(void){
while(!RCIF);
return rx232();
}*/
// ecrit 2 caracteres ascii
tx232_2ascii(unsigned char car){
tx232(hexa2ascii(car >> 4));
tx232(hexa2ascii(car & 0x0F));
}
//========================================================================================
// LECTURE d'un octet dans l'EEPROM
//========================================================================================
unsigned char
readEE(unsigned char adr){
//return EEPROM_READ(adr); // bug -W-3 no effect !!
EEADR = adr; // selectionne la bonne adresse
EEPGD = 0; // memoire donnees
RD = 1; // commence la lecture
return EEDATA; // renvoie l'octet lu-
}
//========================================================================================
// ECRITURE d'un octet dans l'EEPROM
//========================================================================================
writeEE(unsigned char adr, unsigned char data){
//EEPROM_WRITE(adr, data); // avec blocage ISR + remise en route ISR
/*//char tmp;
if (GIE==1) CARRY = 1; // tmp = 1;
else CARRY = 0; // tmp = 0;
while (WR==1); // attend la fin de l'ecriture precedante
EEADR = adr; // selectionne la bonne adresse
EEDATA = data; // donnee a ecrire
EEPGD = 0; // memoire donnees
WREN = 1; // autorise l'ecriture
GIE = 0; // desactive les ISR si activees
EECON2 = 0x55; // nombres magiques
EECON2 = 0xAA; //
WR = 1; // commence l'ecriture
GIE = CARRY; //(bit)tmp; // reactive les interruptions
WREN = 0; // interdit l'ecriture
*/
// HI-TECH macro + Microchip P43 ex4-2
while(WR)continue; // attends la fin de l'ecriture precedante
EEADR=adr; // selectionne la bonne adresse
EEDATA=data; // donnee a ecrire
EEPGD=0; // memoire donnees
WREN=1; // autorise l'ecriture
CARRY=0; // sauvegarde & desactive GIE
if(GIE) CARRY=1;
GIE=0; // desactive les ISR si activees
EECON2=0x55; // nombres magiques
EECON2=0xAA;
WR=1; // commence l'ecriture
if(CARRY) GIE=1; // reactive les interruptions
WREN=0; // interdit l'ecriture
}
/*
// ajoute 37 octets ROM // A TESTER
//========================================================================================
// STOCKAGE variables RAM persistant
//========================================================================================
// LECTURE d'une suite d'octet dans l'EEPROM : ZONE PERSISTANTE
// appel : read_from_eeprom(_Lnvram, _Hnvram-_Lnvram);
//========================================================================================
read_from_eeprom(char * start, unsigned char length){
unsigned char i;
for(i=0; i<length; i++){
*start = readEE(i);
start++;
}
}
//========================================================================================
// ECRITURE d'une suite d'octet dans l'EEPROM : ZONE PERSISTANTE
// appel : write_to_eeprom(_Lnvram, _Hnvram-_Lnvram);
//========================================================================================
write_to_eeprom(char * start, unsigned char length){
unsigned char i;
for(i=0; i<length; i++){
writeEE(i, *start);
start++;
}
}*/
//EOF//