I have been studying microcontrollers so far and I gone through LCD and understood how it worked in 8 bits mode but 1 thing I don't understand is how to work with it in 4 bits mode and whatever I try in code I cant ever make it and I searched almost all the sites available on the internet to explain this topic but still didn't get it so I would very much appreciate if someone could spend some of his time explaining this to me thanks in advance.
#user3674628: By now you must have had known how to interface in 4-bit modes. Though you didnt specify the compiler you use here is an example I have been using with mplabx with xC8 compiler. It works pretty well. Do not forget to adjust the configuration bits on mplabx. Success!
// PIC18F4550 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1L
#pragma config PLLDIV = 5
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2
// CONFIG1H
#pragma config FOSC = INTOSCIO_EC //this uses internal oscillator
#pragma config FCMEN = OFF
#pragma config IESO = OFF
// CONFIG2L
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 3
#pragma config VREGEN = OFF
// CONFIG2H
#pragma config WDT = OFF
#pragma config WDTPS = 32768
// CONFIG3H
#pragma config CCP2MX = ON
#pragma config PBADEN = OFF
#pragma config LPT1OSC = OFF
#pragma config MCLRE = OFF
// CONFIG4L
#pragma config STVREN = ON
#pragma config LVP = OFF
#include <p18f4550.h>
#include <stdio.h>
#include <stdlib.h>
#include <plib/xlcd.h>
/* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT PORTB //for 4-bit mode connect D4-D7 of lcd to B0-B3 of lcd
#define TRIS_DATA_PORT TRISB
/* This defines the port where the control lines are connected.
* These are just samples, change to match your application.
* you may omit this part because its in y the compiler.
*/
#define RW_PIN LATBbits.LATB6
#define TRIS_RW TRISBbits.TRISB6
#define RS_PIN LATBbits.LATB5
#define TRIS_RS TRISBbits.TRISB5
#define E_PIN LATBbits.LATB4
#define TRIS_E TRISBbits.TRISB4
#define _XTAL_FREQ 4000000 // SET THIS TO SUIT YOUR FREQUENCY
void Wait(unsigned int delay)//delay for 100ms
{
for(;delay;delay--)
__delay_us(100);
}
//initialise the lcd
void LCDInit(){
OpenXLCD(FOUR_BIT & LINES_5X7 & CURSOR_ON & BLINK_OFF);
while(BusyXLCD());
WriteCmdXLCD(SHIFT_DISP_LEFT);
while(BusyXLCD());
}
void main(void)
{
ADCON1 = 0xF; // No analog, all digital i/o
TRISB = 0x0;
LCDInit()//initialise lcd
putrsXLCD( " Thanks God" );//display on the lcd
while(BusyXLCD());
WriteCmdXLCD(0xC0);// go to the next line on the lcd
while(BusyXLCD());
putrsXLCD( " I made it" );//display on the lcd
while(BusyXLCD());
while(1);
}
void DelayFor18TCY(void){
Delay10TCYx(20);
}
void DelayPORXLCD(void){
Delay1KTCYx(30);
}
void DelayXLCD(void){
Delay1KTCYx(10);
}
Have you tried these?
http://learningmsp430.wordpress.com/2013/11/16/16x2-lcd-interfacing-in-4-bit-mode/
http://www.spickles.org/projects/4-bit-lcd/
The first is pretty informative, and the second has example source code.
For 4-bit interface data, only four bus lines (DB4 to DB7) are used for transfer. Bus lines DB0 to DB3
are disabled. The data transfer between the HD44780U and the MPU is completed after the 4-bit data
has been transferred twice. As for the order of data transfer, the four high order bits (for 8-bit
operation, DB4 to DB7) are transferred before the four low order bits (for 8-bit operation, DB0 to
DB3).
The busy flag must be checked (one instruction) after the 4-bit data has been transferred twice. Two
more 4-bit operations then transfer the busy flag and address counter data.
For 8-bit interface data, all eight bus lines (DB0 to DB7) are used.
Here is an example on how it works:
#include <msp430g2553.h>
#define DR P1OUT = P1OUT | BIT4 // define RS high
#define CWR P1OUT = P1OUT & (~BIT4) // define RS low
#define READ P1OUT = P1OUT | BIT5 // define Read signal R/W = 1 for reading
#define WRITE P1OUT = P1OUT & (~BIT5) // define Write signal R/W = 0 for writing
#define ENABLE_HIGH P1OUT = P1OUT | BIT6 // define Enable high signal
#define ENABLE_LOW P1OUT = P1OUT & (~BIT6) // define Enable Low signal
void data_write(void)
{
ENABLE_HIGH;
delay(2);
ENABLE_LOW;
}
void data_read(void)
{
ENABLE_LOW;
delay(2);
ENABLE_HIGH;
}
void check_busy(void)
{
P1DIR &= ~(BIT3); // make P1.3 as input
while((P1IN&BIT3)==1)
{
data_read();
}
P1DIR |= BIT3; // make P1.3 as output
}
void send_command(unsigned char cmd)
{
check_busy();
WRITE;
CWR;
P1OUT = (P1OUT & 0xF0)|((cmd>>4) & 0x0F); // send higher nibble
data_write(); // give enable trigger
P1OUT = (P1OUT & 0xF0)|(cmd & 0x0F); // send lower nibble
data_write(); // give enable trigger
}
void send_data(unsigned char data)
{
check_busy();
WRITE;
DR;
P1OUT = (P1OUT & 0xF0)|((data>>4) & 0x0F); // send higher nibble
data_write(); // give enable trigger
P1OUT = (P1OUT & 0xF0)|(data & 0x0F); // send lower nibble
data_write(); // give enable trigger
}
void send_string(char s)
{
while(s)
{
send_data(*s);
s++;
}
}
void lcd_init(void)
{
P1DIR |= 0xFF;
P1OUT &= 0x00;
send_command(0x33);
send_command(0x32);
send_command(0x28); // 4 bit mode
send_command(0x0E); // clear the screen
send_command(0x01); // display on cursor on
send_command(0x06); // increment cursor
send_command(0x80); // row 1 column 1
}
#include “lcd.h”
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // stop watchdog timer
lcd_init();
send_string(“Hello”);
send_command(0xC0);
send_string(“World”);
while(1){}
}
Related
i'm currently trying to use a button as an interrupt. But i'm struggling with it. I've seen in the datasheet that i should enable: INTE bit of PIE0, INTEDG of INTCON, AND GIE if PIE.
I've also seen that i have to use the INTPPS register to configure a pin to be the interrupt, so as i want to use RB0 as an interupt, then i used PIR0bits.INTF to check if the interupt= true in my ISR. I did that :
void ledLoop(unsigned char *ptr){
unsigned char *tmp = ptr;
while(*tmp<64){
LATB = *tmp;
*tmp *= 2;
__delay_ms(200);
}
}
void __interrupt() high_isr(void){
INTCONbits.GIE = 0;
if( PIR0bits.INTF){
LATB = ~LATB;
PIR0bits.INTF = 0;
}
INTCONbits.GIE = 1;
}
void launch(void){
unsigned char run = 1;
while(1){
if(PORTDbits.RD7==1){
unsigned char tmp = 1;
ledLoop(&tmp);
}
if(PORTDbits.RD6==1){
LATB=0xff;
}
else{
LATB=0;
}
}
}
void main(void)
{
ANSELDbits.ANSD7=0;
ANSELDbits.ANSD6=0;
TRISB=0;
TRISA=0;
LATA=0x00;
TRISDbits.TRISD7=1;
TRISDbits.TRISD6=1;
TRISBbits.TRISB0=1;
//GIE: Global Interrupt Enable bit
//PEIE: Peripheral Interrupt Enable bit
PIE0bits.INTE = 1;
INTCONbits.GIE = 1;
INTCONbits.INTEDG = 1;
INTPPSbits.INTPPS = 0x08;
launch();
}
Any idea of what is wrong ?
using :
MPLABX IDE
XC8 Compiler
PIC16F18875
There are three thing wrong with the code you posted:
No configuration words, so code will not build as posted
Changing the GIE bit inside of an ISR
PORTB pin RB0 not configured for digital input
See my comments using /* */ for your code fixed:
/*
* File: main.c
* Author: dan1138
*
* Created on September 24, 2020, 2:23 PM
*/
// PIC16F18875 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FEXTOSC = OFF // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1) (FOSC = 32 MHz))
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (FSCM timer enabled)
// CONFIG2
#pragma config MCLRE = ON // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF // Brown-out reset enable bits (Brown-out reset disabled)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = OFF // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
// CONFIG3
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled, SWDTEN is ignored)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)
// CONFIG4
#pragma config WRT = OFF // UserNVM self-write protection bits (Write protection off)
#pragma config SCANE = available// Scanner Enable bit (Scanner module is available for use)
#pragma config LVP = ON // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)
// CONFIG5
#pragma config CP = OFF // UserNVM Program memory code protection bit (Program Memory code protection disabled)
#pragma config CPD = OFF // DataNVM code protection bit (Data EEPROM code protection disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#define _XTAL_FREQ (32000000ul)
void ledLoop(unsigned char *ptr){
unsigned char *tmp = ptr;
while(*tmp<64){
LATB = *tmp;
*tmp *= 2;
__delay_ms(200);
}
}
void __interrupt() high_isr(void){
//INTCONbits.GIE = 0; /* <= do not do this in an interrupt service routine */
if((PIE0bits.INTE) && ( PIR0bits.INTF)){ /* check that the interrupt is enabled AND asserted */
LATB = ~LATB;
PIR0bits.INTF = 0;
}
//INTCONbits.GIE = 1; /* <= do not do this in an interrupt service routine */
}
void launch(void){
unsigned char run = 1;
while(1){
if(PORTDbits.RD7==1){
unsigned char tmp = 1;
ledLoop(&tmp);
}
if(PORTDbits.RD6==1){
LATB=0xff;
}
else{
LATB=0;
}
}
}
void main(void)
{
ANSELDbits.ANSD7=0;
ANSELDbits.ANSD6=0;
TRISB=0;
TRISA=0;
LATA=0x00;
TRISDbits.TRISD7=1;
TRISDbits.TRISD6=1;
TRISBbits.TRISB0=1;
ANSELBbits.ANSB0=0; /* make RB0 a digital input */
//GIE: Global Interrupt Enable bit
//PEIE: Peripheral Interrupt Enable bit
PIE0bits.INTE = 1;
INTCONbits.GIE = 1;
INTCONbits.INTEDG = 1;
INTPPSbits.INTPPS = 0x08; /* assign INT input to RB0 */
launch();
}
I have this code that I am using to play a sound effect where I used a program called wav2c to convert a .wav file to number values that I put into a header file that I use in the code to generate the sound. I currently have it programmed to play the audio upon uploading it to the Arduino with an LED being activated along with it and staying lit for just the duration of the sound effect. I am trying to program it so that the sound and LED only activate when I am pressing a button. I have the pin the button is plugged into already programmed in but I'm not sure how to have it control the audio and LED as stated above. I don't have much experience with programming or Arduino so any help is much appreciated! I am using an Arduino Mega 2560.
The code
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 20000
#include "Test.h"
int ledPin = 2;
int speakerPin = 9; // Can be either 3 or 11, two PWM outputs connected to Timer 2
const byte pinSwitch1 = 3;
volatile uint16_t sample;
byte lastSample;
void stopPlayback()
{
digitalWrite(ledPin, LOW);
// Disable playback per-sample interrupt.
TIMSK1 &= ~_BV(OCIE1A);
// Disable the per-sample timer completely.
TCCR1B &= ~_BV(CS10);
// Disable the PWM timer.
TCCR2B &= ~_BV(CS10);
digitalWrite(speakerPin, LOW);
}
// This is called at 8000 Hz to load the next sample.
ISR(TIMER1_COMPA_vect) {
if (sample >= sounddata_length) {
if (sample == sounddata_length + lastSample) {
stopPlayback();
}
else {
if(speakerPin==11){
// Ramp down to zero to reduce the click at the end of playback.
OCR2A = sounddata_length + lastSample - sample;
} else {
OCR2B = sounddata_length + lastSample - sample;
}
}
}
else {
if(speakerPin==11){
OCR2A = pgm_read_byte(&sounddata_data[sample]);
} else {
OCR2B = pgm_read_byte(&sounddata_data[sample]);
}
}
++sample;
}
void startPlayback()
{
pinMode(speakerPin, OUTPUT);
// Set up Timer 2 to do pulse width modulation on the speaker
// pin.
// Use internal clock (datasheet p.160)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// Set fast PWM mode (p.157)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
if(speakerPin==11){
// Do non-inverting PWM on pin OC2A (p.155)
// On the Arduino this is pin 11.
TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
// No prescaler (p.158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set initial pulse width to the first sample.
OCR2A = pgm_read_byte(&sounddata_data[0]);
} else {
// Do non-inverting PWM on pin OC2B (p.155)
// On the Arduino this is pin 3.
TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0);
TCCR2A &= ~(_BV(COM2A1) | _BV(COM2A0));
// No prescaler (p.158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set initial pulse width to the first sample.
OCR2B = pgm_read_byte(&sounddata_data[0]);
}
// Set up Timer 1 to send a sample every interrupt.
cli();
// Set CTC mode (Clear Timer on Compare Match) (p.133)
// Have to set OCR1A *after*, otherwise it gets reset to 0!
TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
// No prescaler (p.134)
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set the compare register (OCR1A).
// OCR1A is a 16-bit register, so we have to do this with
// interrupts disabled to be safe.
OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
// Enable interrupt when TCNT1 == OCR1A (p.136)
TIMSK1 |= _BV(OCIE1A);
lastSample = pgm_read_byte(&sounddata_data[sounddata_length-1]);
sample = 0;
sei();
}
void setup()
{
pinMode( pinSwitch1, INPUT );
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
startPlayback();
}
void loop()
{
while (true);
}
The header file referenced in the code with the numeric values to create the audio.
#ifndef _HEADERFILE_H // Put these two lines at the top of your file.
#define _HEADERFILE_H // (Use a suitable name, usually based on the file name.)
const int sounddata_length=32000;
//const int sounddata_sampleRate=20000;
const unsigned char sounddata_data[] PROGMEM = {
15,1,49,0,150,0,138,0,219,255,133,0,176,0,15,1,210,
//There are many lines of more numbers in between that I cut out to save space
};
#endif // _HEADERFILE_H // Put this line at the end of your file.
The following changes will allow you to start playback whenever there is a falling edge on your switch pin. You may need to tweak to avoid switch 'bouncing'.
Firstly, add a global variable to record the last switch state:
int lastSwitchState;
Change your setup() to
void setup() {
pinMode(pinSwitch1, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
lastSwitchState = digitalRead(pinSwitch1);
}
and your loop() function to
void loop() {
delay(50);
int switchState = digitalRead(pinSwitch1);
if (switchState != lastSwitchState) {
lastSwitchState = switchState;
if (switchState == LOW) {
startPlayback();
}
}
}
Interrupts vs polling
Instead of polling the switch pin inside the main loop(), you could use interrupts. You would use attachInterrupt() to do this. Interrupts are only available on certain pins, however, and the above approach is conceptually simpler I think.
HI I'm trying to implement simple spi communication to turn on 8 led connected to shift register can amy one help me whats wrong with this code, im getting random output, I want to send 0x02 to turn on led(00000010) .
#include <xc.h>
#include "spi.h"
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage In-Circuit Serial Programming Enable bit
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit
#pragma config WRT = OFF // Flash Program Memory Write Enable bits
#pragma config CP = OFF // Flash Program Memory Code Protection bit
#define _XTAL_FREQ 8000000
void main()
{
char data = 0x10;
spiInit(SPI_MASTER_OSC_DIV4, SPI_DATA_SAMPLE_END, SPI_CLOCK_IDLE_LOW, SPI_IDLE_2_ACTIVE);
TRISC0 = 0;
RC0 = 1;
RC3 = 0;
RC5 = 0;
while(1)
{
RC0 = 0; //Slave Select
__delay_ms(100);
spiWrite(data);
while(!SSPSTATbits.BF);
__delay_ms(100);
RC0= 1; //Slave Deselect
}
}
I'm trying to use the MSPF5529 with my mac. I've downloaded code composer studio and can easily access the chip as well as blink lights and any other application I need.
The goal is for me to print a message using UART through serial communication on my Mac. I am currently using an application called "goSerial" in order to communicate with the chip. My code below initializes UART, takes in a single character, and then it is supposed to print out a character, and then blink a light. However, instead, the code takes in the character, and prints out a strange symbol, called a spacing cedilla, with a hex value of 0xFC, and then blinks the light.
This symbol appears regardless of which character I put into the MSP430 buffer.
My code is listed below. Has anyone had this problem before? How do I solve this?
void Init_UART(void);
void OUTA_UART(unsigned char A);
unsigned char INCHAR_UART(void);
#include "msp430f5529.h"
#include "stdio.h"
int main(void){
volatile unsigned char a;
volatile unsigned int i;
WDTCTL = WDTPW + WDTHOLD;
Init_UART();
a=INCHAR_UART();
a=INCHAR_UART();
OUTA_UART(a);
// go blink the light to indicate code is running
P1DIR |= 0x01;
for (;;){
P1OUT ^= 0x01; i = 10000;
do i--;
while (i != 0); }
}
void OUTA_UART(unsigned char A){
while ((UCA1STAT&UCBUSY));
// send the data to the transmit buffer
UCA1TXBUF =A;
}
unsigned char INCHAR_UART(void){
while ((UCA1STAT&UCBUSY) == 0);
// go get the char from the receive buffer
return (UCA1RXBUF);
}
void Init_UART(void){
P4SEL |= 0x30; // Port 4.4 and port 4.5 controls the transfer
UCA1CTL1|= UCSWRST; // Put state machine in reset
UCA1CTL1|= UCSSEL_1; //Choose 32765Hz
UCA0BR0=3; // Baud rate = 9600
UCA0BR1=0; // Choose 32765 hz
UCA1MCTL=0x06; // Modulation UCBRSx=3, UCBFx = 0
UCA1CTL1 &= ~UCSWRST; // Put USCI in operation mode
}
The UCBUSY flag is not very useful, and cannot be used like this.
That a byte has been received is indicated by UCRXIFG:
while (!(UCA1IFG & UCRXIFG)) ;
return UCA1RXBUF;
That a byte can be sent is indicated by UCTXIFG:
while (!(UCA1IFG & UCTXIFG)) ;
UCA1TXBUF = a;
I am using MPlab to read data from a pic micro controller. I am using pic18F87J11.
The data that I want to read is on pin 3 of the DB9 of the RS232, and my RS232 is connected to the pic micro controller.
Can anyone help me or give me a simple sample code to do that??
Thank you,
//
// Designed by www.MCUExamples.com
// rasika0612#gmail.com
// Serial communications example. Echo data comes to serial port
// using serial receive interrupt.
//
#include <p18f4520.h>
#pragma config OSC = HS // 20MHz Crystal, (HS oscillator)
#pragma config PBADEN = OFF // PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config WDT = OFF // watch dog timer off
#pragma config LVP = OFF // Low voltage program off
unsigned char cUART_char;
unsigned char cUART_data_flg;
void init_uart(void);
void UART_putc(unsigned char c);
void InterruptHandlerLow ();
void main()
{
init_uart(); // init UART module
while (1) // infinite loop which handles ncoming data as they arrive
{
if (cUART_data_flg==1)// if new data available, send it back through USART tx line (echo it)
{
UART_putc(cUART_char);
cUART_data_flg=0; // clear new data flag so one charactor will echoed once
}
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow (void)
{
_asm
goto InterruptHandlerLow //jump to interrupt routine
_endasm
}
//----------------------------------------------------------------------------
// Low priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerLow
void InterruptHandlerLow ()
{
if (PIR1bits.RCIF==1)//is interrupt occured by EUSART receive?,
//then RCREG is full we have new data (cleared when RCREG is read)
{
if(RCSTA&0x06) //more efficient way than following commented method to check for reception error
//if(RCSTAbits.FERR==1 || RCSTAbits.OERR==1 )
{
RCSTAbits.CREN=0; //Overrun error (can be cleared by clearing bit CREN)
cUART_char=RCREG; //clear Framing error
RCSTAbits.CREN=1;
}
else
{
cUART_char = RCREG; // read new data into variable
cUART_data_flg = 1; // new data received. so enable flg
}
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void init_uart(void) // init UART module for 9600bps boud, start bit 1, stopbit 1, parity NONE
{
cUART_data_flg=0; // init data receive flag to zero (no data)
TRISCbits.TRISC7=1; //Make UART RX pin input
TRISCbits.TRISC6=0; //Make UART TX pin output
SPBRGH = 0x02; //9600bps 20MHz Osc
SPBRG = 0x08;
RCSTAbits.CREN=1; //1 = Enables receiver
RCSTAbits.SPEN=1; //1 = Serial port enabled (configures RX/DT and TX/CK pins as serial port pins)
BAUDCONbits.BRG16=1;//1 = 16-bit Baud Rate Generator – SPBRGH and SPBRG
TXSTAbits.SYNC=0; //0 = Asynchronous mode
TXSTAbits.BRGH=1; //1 = High speed
TXSTAbits.TXEN=1; //1 = Transmit enabled
RCONbits.IPEN = 1; //enable Interrupt priority levels
IPR1bits.RCIP=0; // EUSART Receive Interrupt Priority 0 = Low priority
PIE1bits.RCIE=1; // 1 = Enables the EUSART receive interrupt
INTCONbits.GIEL = 1;//enable interrupts
INTCONbits.GIEH = 1;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void UART_putc(unsigned char c)
{
TXSTAbits.TXEN=0;// disable transmission
TXREG=c; // load txreg with data
TXSTAbits.TXEN=1; // enable transmission
while(TXSTAbits.TRMT==0) // wait here till transmit complete
{
Nop();
}
}