Jump to content

gordon@cil-uk.co.uk

EstablishedMember
  • Content Count

    32
  • Joined

  • Last visited

Community Reputation

0 Neutral

About gordon@cil-uk.co.uk

  • Rank
    Regular
  1. One last curiosity. When I grafted this back itno the main project, I omitted to correct the ansel = ANS1 line, but the program still works and for Microchip's documentation, I think it should not have. Hmm.
  2. I appear to have a working A/D, though not without some notable problems. FYI, here's how it went..... I found one bug -- using a bit index as a value in ansel, however it still wouldn't work as there were some other problems. To cover all the possible timing/delay situations (too quick, too slow, various register settings) I set each part of adcon0 separately, with a fairly substantial delay between them. I doubt I need them all, or so long, but I don't have time right now to tune them or remove surplus delays. Despite using the slower of the recommended Tad setting (Fosc/16 on the 4MHz intrc clock should be 4us), Microchip's MPLAB-Sim complained that Tad was too low at 1.6us. Changing it to use the Frc oscillator actually gave me back a DONE signal from that simulator, but still did not from the SourceBoost simulator (?). I then tried it in some hardware and got something in adresh:adresl. I then took the modified code and grafted it back into the real application, which is a touch more difficult to debug and, at last, I get back some results. A litle tidying should see it done, if rather overdue. Here's the code I ended up with. I'd earlier spent some more time cutting out more code superlfuous to the problem. There's really not much left. #include <system.h> //Target PIC16F676 configuration word #pragma DATA _CONFIG, _PWRTE_OFF & _WDT_OFF & _CP_OFF & _INTRC_OSC_NOCLKOUT //Set clock frequency #pragma CLOCK_FREQ 4000000 #define ADCH1 (0x01 << CHS0) char adc; /****** main ******/ main() { // initialize peripherals and the application option_reg = 0x5F; // IO ports setup wpu = 0; trisa = 0x2B; // Port RA5, MCLR, RA1 and RA0 are inputs porta = 0x00; // All low (pump off, SEG_A On). trisc = 0x00; // Port C is all outputs. portc = 0x00; // All SEGs On. cmcon = 0x07; // TODO Port-A says 0x05; fig 6-2 says 0x07? -- 0x07 appears saner. // ansel = ANS1; // <<=== wrong! ansel = (1<<ANS1); // RA1 is LDR input // adcon1 = 0x50; // Fosc/16 adcon1 = 0x70; // Frc // initialise some data. adc = 0; // enable global, peripheral, T0 interrupts intcon = 0; while(1) { char i; // Setup the A/D to read adcon0 = ADCH1; // select AN1 for( i=30; i; i-- ) // Pause for no known reason .. desperation setting in here. {} set_bit( adcon0, ADON ); // Start the A/D for( i=30; i; i-- ) // Pause for signal acquisition. {} set_bit( adcon0, GO); // start the conversion while( adcon0&(1<<GO) ) // wait for a `done' indication. {} adc = adresh; // get the result ( never gets here! ) i = 0; // somewhere to hang a breakpoint. } }
  3. It appears I can't do this: adcon0 = ADCH1|(1<<ADON)|(1<<GO); // AN1 and go. I have to wait a while before starting the conversion. ... which I now do, but still with no success
  4. It appears I can't do this: adcon0 = ADCH1|(1<<ADON)|(1<<GO); // AN1 and go. I have to wait a while before starting the conversion. ... which I now do, but still with no success
  5. Hi Guys, This has to be an error by me, but I can't presently see it. I'm trying to do a simple polled ADC on port RA1, but whatever I try, I get zero in adresh:adresl from both the simulator and real hardware. Here's a heavilly stripped down extract from the application: /******************************************************************** Filename: Try.c */ #include <system.h> //Target PIC16F676 configuration word #pragma DATA _CONFIG, _PWRTE_OFF & _WDT_ON & _CP_OFF & _INTRC_OSC_NOCLKOUT // _INTRC_OSC_NOCLK not valid?? //#pragma DATA _CONFIG, 0x3FF4 //Set clock frequency #pragma CLOCK_FREQ 4000000 #define ADCH0 (0x00 << CHS0) #define ADCH1 (0x01 << CHS0) #define ADCH2 (0x02 << CHS0) #define ADCH3 (0x03 << CHS0) #define ADCH4 (0x04 << CHS0) #define ADCH5 (0x05 << CHS0) #define ADCH6 (0x06 << CHS0) #define ADCH7 (0x07 << CHS0) char tick; char hundredths; char tenths; char seconds; char adc; /****************************************************/ void interrupt( void ) { // timer 0 interrupt if ( intcon&0x20 && intcon&0x04 ) { tmr0 = 6; clear_bit( intcon, T0IF ); tick = 1; } } /*******************************************************/ main() { // initialize peripherals and the application option_reg = 0x5F; // IO ports setup wpu = 0; trisa = 0x2B; // Port RA5, MCLR, RA1 and RA0 are inputs porta = 0x00; // All low (pump off, SEG_A On). trisc = 0x00; // Port C is all outputs. portc = 0x00; // All SEGs On. cmcon = 0x07; // TODO Port-A says 0x05; fig 6-2 says 0x07? ansel = ANS1; // RA1 is LDR input //adcon1 = 0x50; // Fosc/16 adcon1 = 0x70; // internal R/C adcon0 = ADCH1|(1<<ADON)|(1<<GO); // AN1 and go. // initialise some data. tick = 0; adc = 0; hundredths = 0; tenths = 0; // timer 0 setup tmr0 = 6; // enable peripheral and global interrupts intcon = 0xE0; while(1) { if( tick ) { tick = 0; // every tenth of second if ( ++hundredths >= 10 ) { hundredths = 0; // every second if ( ++tenths >= 10 ) { tenths = 0; // Read the A/D adc = adresh; // Start the next reading. adcon0 = ADCH1|(1<<ADON)|(1<<GO); // this is => adcon0 = 0x07 } } } // tum-ti-tum .. so much waiting around, maybe another coffee? } } Anyone see and correct my deliberate mistake, please? Thanks, Gordon
  6. I think I was mistaken about 2). I compiled but didn't link and looked at the .asm file, but I now think the .asm file wasn't rewritten. --------8<---------------------------- Running the 6.31 compiler from SourceBoost with either a combined or a separate eeprom.c file containing the eeprom code, I get good code. Running the same from MPLab, I continue to get bad code. (Irritatingly, I can't cut and paste the compile report.) Retyped significant bits from SourceBoost are (E&OE): "C:\Program Files\SourceBoost\boost.pic18.exe" -t PIC18F2420 Pod.c eeprom.c ......Version 6.31 (for PIC18 achitecture) ... and the equivalent from MPLab are: Executing: "C:\Program Files\SourceBoost\boostc.pic18.exe" eeprom.c -O0 -W1 -t 18F2420 BoostC Optimizing C Compiler Version 6.31 (for PIC18 architecture) http://www.picant.com/c2c/c.html Copyright(C) 2004-2006 Pavel Baranov Copyright(C) 2004-2006 David Hobday ..which looks suspiciously like, maybe, an optimisation problem? Trying that out (sounds off) Turned optimisation ON and the code is right. That's an inverse of the usual way on things....... Just for the record, it writes the real physical EEPROM OK, too, so my problem seems fixed. I still reckon that's a bug, though.
  7. Just tried a couple of other things: 1) Moved the eeprom code from it's separate source file into the main source file. The eeprom code is now virtually the first code in the main file (after a one-statement error trap). No change. 2) Then switched back from MPLab to the SourceBoost IDE in case it's IDE related. No change. I'm using a slightly older compiler version (6.30), though I see no reference to changes in this area. Maybe I should update anyway
  8. I have posted some more in that thread and will continue there rather than here, to avoid duplications.
  9. Curious! For compaerison and to hope it helps give a clue what's going on, here are the equivalent lines from my file. I've included the entire code block and marked the relevant bit. ORG 0x00000972 0972 eeprom_wri_00008 ; { eeprom_write; function begin 0972 label268437115 0972 0E02 MOVLW 0x02 0974 010F MOVLB 0x0F 0976 14A6 ANDWF gbl_eecon1, W 0978 E001 BZ label268437116 097A D7FB BRA label268437115 097C label268437116 097C 0102 MOVLB 0x02 097E 5106 MOVF eeprom_wri_00008_arg_address, W, 1 0980 010F MOVLB 0x0F 0982 6EA9 MOVWF gbl_eeadr 0984 0102 MOVLB 0x02 0986 5107 MOVF eeprom_wri_00008_arg_data, W, 1 0988 010F MOVLB 0x0F 098A 6EA8 MOVWF gbl_eedata 098C 0E7F MOVLW 0x7F 098E 010F MOVLB 0x0F 0990 16A6 ANDWF gbl_eecon1, F 0992 0EBF MOVLW 0xBF 0994 010F MOVLB 0x0F 0996 16A6 ANDWF gbl_eecon1, F 0998 0EF7 MOVLW 0xF7 099A 010F MOVLB 0x0F 099C 16A6 ANDWF gbl_eecon1, F 099E 010F MOVLB 0x0F 09A0 84A6 BSF gbl_eecon1,2 09A2 0E7F MOVLW 0x7F 09A4 010F MOVLB 0x0F 09A6 16F2 ANDWF gbl_intcon, F --------8<------------------------------------ 09A8 0E55 MOVLW 0x55 09AA 010F MOVLB 0x0F 09AC 6EA7 MOVWF gbl_eecon2 09AE 0EAA MOVLW 0xAA 09B0 010F MOVLB 0x0F 09B2 6EA7 MOVWF gbl_eecon2 09B4 010F MOVLB 0x0F 09B6 82A6 BSF gbl_eecon1,1 --------8<------------------------------------ 09B8 010F MOVLB 0x0F 09BA 8EF2 BSF gbl_intcon,7 09BC label268437127 09BC 0E02 MOVLW 0x02 09BE 010F MOVLB 0x0F 09C0 14A6 ANDWF gbl_eecon1, W 09C2 E001 BZ label268437128 09C4 D7FB BRA label268437127 09C6 label268437128 09C6 0EFB MOVLW 0xFB 09C8 010F MOVLB 0x0F 09CA 16A6 ANDWF gbl_eecon1, F 09CC label268437131 09CC 0E08 MOVLW 0x08 09CE 010F MOVLB 0x0F 09D0 14A6 ANDWF gbl_eecon1, W 09D2 E001 BZ label268437132 09D4 D7FB BRA label268437131 09D6 label268437132 09D6 0012 RETURN ; } eeprom_write function end
  10. Sorry .. forgot vital information: Executing: "C:\Program Files\SourceBoost\boostc.pic18.exe" Pod.c -O0 -W1 -t 18F2420 BoostC Optimizing C Compiler Version 6.30 (for PIC18 architecture) http://www.picant.com/c2c/c.html Copyright(C) 2004-2006 Pavel Baranov Copyright(C) 2004-2006 David Hobday
  11. Hi Guys, This appears to be a conflict between BoostC's output and the PIC's "required sequence". Bug report posted. For completeness in this thread: PIC18F2420 (and I presume others in the series) demands: MOVLW 0x55 MOVWF _eecon2 MOVLW AAh MOVWF _eecon2 BSF _eecon1, WR but BoostC, even using the above code in an inline asm{} is generating: MOVLW 0x55 MOVLB 0x0F MOVWF gbl_eecon2 MOVLW 0xAA MOVLB 0x0F MOVWF gbl_eecon2 MOVLB 0x0F BSF gbl_eecon1,1 which apparently is not good enough as "the reason the WR bit cannot be set is because there is an interruption in the middle of the required sequence, i.e. 'MOVLB 0x0F'." Ho Hum.
  12. Hi Guys, I've been chasing a "can't write EEPROM" problem that looks like is't a compiler/chip incompatibility. Microchip's "required sequence" to do the write is: MOVLW 0x55 MOVWF EECON2 MOVLW AAh MOVWF EECON2 BSF EECON, WR But BoostC seems to be generating: MOVLW 0x55 MOVLB 0x0F MOVWF gbl_eecon2 MOVLW 0xAA MOVLB 0x0F MOVWF gbl_eecon2 MOVLB 0x0F BSF gbl_eecon1,1 even with the "required sequence" written as an inline asm{} block. Microchip commented thus: --------8<-------------------------------------------------------------- Description: Unable to write internal EEPROM. Resolution: Thank you for attaching the disassembly. This shows where the problem is. MOVLW 0x55 MOVLB 0x0F MOVWF gbl_eecon2 MOVLW 0xAA MOVLB 0x0F MOVWF gbl_eecon2 MOVLB 0x0F BSF gbl_eecon1,1 The 'required sequence' of writing 0x55,0xAA to the EECON2 register must be followed before the WR bit can be set. Referring to the disassembly above, the reason the WR bit cannot be set is because there is an interruption in the middle of the required sequence, i.e. 'MOVLB 0x0F'. I am not sure why this compiler generates banking instructions such as this when SFRs are accessed because they reside in Access RAM. This seems inefficient. If using inline assembly in the C code allows you to avoid the 'MOVLB' instructions in the above sequence then this should allow the WR bit be set and the write should succeed. --------8<--------------------------------------------------------------
  13. I was pretty sure I'd tried that, but tried it again to be sure. My closing lines are now: set_bit( eecon1, WR ); set_bit( intcon, GIE ); // enable interrupts while(eecon1 & (1<<WR) ); clear_bit( eecon1, WREN ); while(eecon1 & (1<<WRERR) ); } ... but the behaviour is the same. One thing I notice and that may _well_ be a clue, is that I don't actually see the WR flag set. I [allegedly] set it, but don't see it, which is somewhat suspicious. The datasheet says it's disabled during Tpwrt, but I understand that timer has to expire before the CPU will run, so should not be implicated. There are some EEPROM protect bits in the configuration data, but I have checked that they're all 'Disabled'. so again, I don't believe they can be implicated. Gordon.
  14. Hi guys, I'm trying to write to the internal EEPROM of a PIC18F2420, but I don't seem to be able to get it to write. Everyhting I try leaves the data unchanged and has the WRERR flag set in eecon2. Here follows what I'm using, showing a couple of variations I've tried (thjough I've tried _many_ more). The code never (well, > 10 seconds) exits from the final while loop. Anyone see a deliberate error in here please? void eeprom_write(char address, char data) { // Pause here if still writing previous data // while(eecon1 & (1<<WR) ); // while(pir2 & (1<<EEIF) ); // Write the next data // eeadr = address; eedata = data; clear_bit( eecon1, EEPGD ); clear_bit( eecon1, CFGS ); clear_bit( eecon1, WRERR ); set_bit( eecon1, WREN ); clear_bit( intcon, GIE ); // disable interrupts #if 0 eecon2 = 0x55; eecon2 = 0xAA; #else asm { MOVLW 0x55 MOVWF _eecon2 MOVLW AAh MOVWF _eecon2 } #endif set_bit( eecon1, WR ); clear_bit( eecon1, WREN ); set_bit( intcon, GIE ); // enable interrupts while(eecon1 & (1<<WRERR) ); } TIA Gordon.
×
×
  • Create New...