zia.newversion
Member level 5
Hi there.
So...
I am back again with another problem. Here is the code (asm).
The purpose of the program to transmit the data on a parallel port to USART TX line (using built in module - NOT manual implementation of USART).
There will be a DIP switch on PORTD in my conceived hardware model, with LED on switch to indicate if it is on or off. There will be MAX232 or relevant on USART outputs (but Proteus does not require it AFAIK).
In addition to that, there will be a selection switch on RA1, which will be used by controller to decide whether to use automatic or manual transmission modes.
In automatic mode, the controller automatically transmits whatever is on PORTD when a TMR0 interrupt occurs (which it does very frequently). This mode is useful when taking sampled data from an external ADC, for example. In manual mode, the controller will require a hardware INT or RB0/INT to be provided for it to start tranmission.
And that's that. The code:
I have revised the code many times so as not to mickey myself out because of some silly mistake. It seems (to me) there is no silly mistake. However, there is no guarantee.
In any case, the ISIS simulation files and MPLAB project files are attached. If anyone could look into what is causing the problem, I shall be duly grateful.
P.S. I know the algorithm has some design flaws. I did not have time to re-evaluate my approach. So I am posting it as is. I shall be making changes to the algorithm (_sthint and _sttint are placed at awkward positions, I was thinking more like enabling both INT and TMR0 interrupts, and then polling them in ISR). But apart from that, if I could make this one work, I shall be able to optimize and remove the design or approach flaws later.
So...
I am back again with another problem. Here is the code (asm).
The purpose of the program to transmit the data on a parallel port to USART TX line (using built in module - NOT manual implementation of USART).
There will be a DIP switch on PORTD in my conceived hardware model, with LED on switch to indicate if it is on or off. There will be MAX232 or relevant on USART outputs (but Proteus does not require it AFAIK).
In addition to that, there will be a selection switch on RA1, which will be used by controller to decide whether to use automatic or manual transmission modes.
In automatic mode, the controller automatically transmits whatever is on PORTD when a TMR0 interrupt occurs (which it does very frequently). This mode is useful when taking sampled data from an external ADC, for example. In manual mode, the controller will require a hardware INT or RB0/INT to be provided for it to start tranmission.
And that's that. The code:
Code ASM - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 list p=16f877 #include "p16f877.inc" ; LP Oscillator between OSC1 OSC2 pins ; Watchdog timer is off ; All code protection is off ; Brown-Out Reset is enabled ; EEPROM data protection is off ; Write to EEPROM enabled ; ICD is off, RB6 and RB7 are GPIO __config _LP_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_ON & _LVP_OFF & _CPD_OFF & _WRT_ENABLE_ON & _DEBUG_OFF org 0x0000 _resetv call _boot goto _main org 0x0004 _intv goto _isr org 0x0010 _boot ; Disable pullups B7=1 ; Interrupt on rising edge B6=1 ; TMR0 runs on internal instruction cycle B5=0 ; TMR0 increments on low-high transition B4=0 ; Prescalar 1:2 assigned to TMR0 B3=0 <B2:B0>=000 (Overflow time = 2 x 256 x Tosc) banksel OPTION_REG movlw 0xC0 movwf OPTION_REG ; Disable all interrupts ; Clear all interrupt flags banksel INTCON clrf INTCON ; Disable all peripheral interrupts ; Clear all peripheral interrupt flags banksel PIE1 clrf PIE1 clrf PIE2 banksel PIR1 clrf PIR1 clrf PIR2 ; Disable ADC module by clearing ADCON0 and ADCON1 banksel ADCON0 clrf ADCON0 banksel ADCON1 movlw 0x06 movwf ADCON1 ; We are transmitting at 9600 baud/s with LP Oscillator @ 4MHz ; To set a Baud Rate of 9.6 Kbdps, SPBRG should be initialized with 25(decimal) banksel SPBRG movlw 0x19 movwf SPBRG ; We are using asynchronous serial tranmission (RS232) ; For that, SYNC bit of TXSTA must be cleared bcf TXSTA, SYNC ; Just because datasheet says so, enable SPEN banksel RCSTA bsf RCSTA, SPEN ; Finally, enable the transmitter by setting TXEN ; Enabling transmitter now will ensure nothing goes wrong in _main sub banksel TXSTA bsf TXSTA, TXEN return _main ; Make all ports output ; Even if we don't have to use all of them. banksel TRISA clrf TRISA clrf TRISB clrf TRISC clrf TRISE ; Make TRISD input. That is our dip-switch parallel input port. movlw 0xFF movwf TRISD ; Make RA1 input ; This pin will be used by user to set automatic/manual transmission modes. bsf TRISA, RA1 ; In automatic mode, controller transmits after every TMR0 overflow interrupt. ; In manual mode, external hardware interrupt (RB0) must be activated to transmit. ; Clear all ports banksel PORTA clrf PORTA clrf PORTB clrf PORTC clrf PORTD clrf PORTE ; Enable interrupts globally banksel INTCON bsf INTCON, GIE _loop ; RA1 enabled = automatic mode | RA1 disabled = manual mode ; In automatic mode, controller transmits after every TMR0 overflow interrupt. ; In manual mode, external hardware interrupt (RB0) must be activated to transmit. banksel PORTA btfss PORTA, RA1 goto _sthint goto _sttint goto _loop _sthint ; Set hardware interrupt and clear timer interrupt banksel INTCON bcf INTCON, T0IE bsf INTCON, INTE goto _loop _sttint ; Set timer interrupt and clear hardware interrupt banksel INTCON bcf INTCON, INTE banksel TMR0 clrf TMR0 bsf INTCON, T0IE goto _loop _isr call _tx ; Like always, clear flags before exiting ISR otherwise the program will keep looping in ISR banksel INTCON bcf INTCON, INTF bcf INTCON, T0IF retfie _tx banksel PORTD movf PORTD, W return ; TRMT is enabled, TSR is empty, tranmission completed - Return from routine end
I have revised the code many times so as not to mickey myself out because of some silly mistake. It seems (to me) there is no silly mistake. However, there is no guarantee.
In any case, the ISIS simulation files and MPLAB project files are attached. If anyone could look into what is causing the problem, I shall be duly grateful.
P.S. I know the algorithm has some design flaws. I did not have time to re-evaluate my approach. So I am posting it as is. I shall be making changes to the algorithm (_sthint and _sttint are placed at awkward positions, I was thinking more like enabling both INT and TMR0 interrupts, and then polling them in ISR). But apart from that, if I could make this one work, I shall be able to optimize and remove the design or approach flaws later.