Issue with Interfacing atmega328p with Bluetooth - avr

I’m trying to interface atmega328p with Blutooth HC-0.
I was following the example in Atmega328P datasheet in USART section.
The code is simply trying to send a letter 'b' to Bluetooth terminal on mobile phone and receive a letter. If the received letter is 'a', an LED on PORTB0 will turn on, if the letter is 'c', the LED will turn off. But unfortunately nothing is working.
Connection between atmega328P and HC-05 is as follows:
HC-05 -> Atmega328P
RXD -> pin3
TXD -> pin2
GND -> pin8
VCC -> pin7
Bluetooth light is turning on and off, and is connected successfully to mobile phone but no data is received, and when the letters 'a' and 'c' are sent nothing happens with LED connected to PORTB0.
The code is shown here. Thank you for any help!
#define F_CPU 16000000UL // Clock Speed
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
char data;
char data2 = 'b';
void USART_Init(unsigned int ubrr)
{
/* Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)(ubrr);
/* Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
char USART_Receive(void)
{
/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC0)) );
/* Get and return received data from buffer */
return UDR0;
}
void USART_Transmit(char data)
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) );
/* Put data into buffer, sends the data */
UDR0 = data;
}
int main(void)
{
DDRB = 0b00000001;
PORTB = 0b00000000;
USART_Init(MYUBRR);
while (1) {
data = USART_Receive();
USART_Transmit(data2);
if (data == 'a') {
PORTB = 0b00000001;
} else if (data == 'c') {
PORTB = 0b00000000;
}
}
}

Related

Can't initialize Qapass 1602A LCD with PIC18F4620

I can't initialize a QAPASS 1602A LCD with a PIC18F4620, I always get square blocks on both lines. In the beginning, I thought the LCD was broken so I got a new one but the outcome is the same. I use a logifind PIC 40 Mini development board connected to PC through a PICkit3, everything else is working fine on every port but not the LCD.
Thanks a lot for your help.
//main.c
#include "newxc8_header.h"
#include <xc.h>
#include "lcd_16x2.h"
void main(void) {
ADCON1=0x0F; //configuring all analog ports to digital
TRISB=0x00; //Set RBs as output
TRISD=0x00; //Set RDs as output
TRISE=0x00; //Set REs as output
LCD_Init(); //Initialize 16x2 LCD
LCD_String("Hello");
while(1);
}
//lcd_16x2.c
#include "lcd_16x2.h"
void LCD_Init(void)
{
__delay_ms(1000);
EN = 0;
RS = 0;
ldata = 0x00;
LCD_Command(0x38); // Initialization of 16X2 LCD: 8-bit, 2 Lines, 5x7 Dots
LCD_Command(0x0C); // Display ON Cursor OFF
LCD_Command(0x01); //clear LCD
LCD_Command(0x02); //cursor beginning first line
}
void LCD_Command(unsigned char cmd)
{
ldata = cmd; /* Send data to PORT as a command for LCD */
RS = 0; /* Command Register is selected */
EN = 1; /* High-to-Low pulse on Enable pin to latch data */
__delay_ms(5);
EN = 0;
__delay_ms(3);
}
void LCD_Char(unsigned char data)
{
ldata = data; /* Send data to LCD */
RS = 1; // Data Register is selected */
EN = 1; // High-to-Low pulse on Enable pin to latch data */
__delay_ms(5);
EN = 0;
__delay_ms(3);
}
void LCD_String(const char *msg)
{
while(*msg != 0)
{
LCD_Char(*msg);
msg++;
}
}
//lcd_16x2.h
#ifndef LCD_16X2_H
#define LCD_16X2_H
#ifdef __cplusplus
extern "C" {
#endif
#include <xc.h>
#define _XTAL_FREQ 16000000 //16 MHz (4 MHz x 4 PLL)
#define ldata LATB /*PORTB(RB0-RB7) is used for transmitting data to LCD*/
#define RS LATEbits.LATE0 /*RE0 pin is used for Register Select*/
#define EN LATEbits.LATE1 /*RE1 pin is used for Enable*/
void LCD_Init(void);
void LCD_Command(unsigned char );
void LCD_Char(unsigned char x);
void LCD_String(const char *);
void LCD_Clear();
#ifdef __cplusplus
}
#endif
#endif /* NEWFILE_H */
Your question does not contain enough details for a definitive answer.
The best guess is that you have a wiring error between your LogiFind PIC-40-MINI board:
and your QAPASS 1602A LCD module:
A photograph of how they are connected would be helpful.
If you are convinced the wiring is correct then a problem may be in the LCD_Init() function, see HD44780 data sheet page 45 for a flowchart about initializing the module in 8-bit parallel mode or in the code you have not posted.
Added on January 19, 2020:
I assembled a PIC18F4620 and LCD module as you described.
Found that your code as posted does not show the configuration words you are using.
When using the internal oscillator at the default frequency (1MHz) your code runs but it's 16 times slower than expected.
After adjusting some settings this is the final version of code:
//main.c
// PIC18F4620 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1H
#pragma config OSC = INTIO67 // Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-003FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (004000-007FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (008000-00BFFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (00C000-00FFFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-003FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (004000-007FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (008000-00BFFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (00C000-00FFFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (004000-007FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
#include <xc.h>
#include "lcd_16x2.h"
void main(void) {
OSCCON = 0b01100000; // sets clock = 4MHz
OSCTUNE = 0b01000000; // turn on 4xPLL
ADCON1=0x0F; //configuring all analog ports to digital
TRISB=0x00; //Set RBs as output
TRISD=0x00; //Set RDs as output
TRISE=0x00; //Set REs as output
LCD_Init(); //Initialize 16x2 LCD
LCD_Command(0x80);
LCD_String("Hello");
LCD_Command(0xC0);
LCD_String(__TIME__ " v1 ");
while(1);
}
//lcd_16x2.c
#include <xc.h>
#include "lcd_16x2.h"
void LCD_Init(void)
{
__delay_ms(1000);
EN = 0;
RS = 0;
LCD_Command(0x38); // Initialization of 16X2 LCD: 8-bit, 2 Lines, 5x7 Dots
LCD_Command(0x0C); // Display ON Cursor OFF
LCD_Command(0x01); //clear LCD
LCD_Command(0x02); //cursor beginning first line
}
void LCD_Command(unsigned char cmd)
{
ldata = cmd; /* Send data to PORT as a command for LCD */
RS = 0; /* Command Register is selected */
EN = 1; /* High-to-Low pulse on Enable pin to latch data */
__delay_us(1);
EN = 0;
__delay_ms(4);
}
void LCD_Char(unsigned char data)
{
ldata = data; /* Send data to LCD */
RS = 1; // Data Register is selected */
EN = 1; // High-to-Low pulse on Enable pin to latch data */
__delay_us(1);
EN = 0;
__delay_us(50);
}
void LCD_String(const char *msg)
{
while(*msg != 0)
{
LCD_Char(*msg);
msg++;
}
}
//lcd_16x2.h
#ifndef LCD_16X2_H
#define LCD_16X2_H
#ifdef __cplusplus
extern "C" {
#endif
#include <xc.h>
#define _XTAL_FREQ 16000000 //16 MHz (4 MHz x 4 PLL)
#define ldata LATB /*PORTB(RB0-RB7) is used for transmitting data to LCD*/
#define RS LATEbits.LATE0 /*RE0 pin is used for Register Select*/
#define EN LATEbits.LATE1 /*RE1 pin is used for Enable*/
void LCD_Init(void);
void LCD_Command(unsigned char );
void LCD_Char(unsigned char x);
void LCD_String(const char *);
void LCD_Clear();
#ifdef __cplusplus
}
#endif
#endif /* NEWFILE_H */

AVR Atmega32a USART library isn't working

/*
RC_Car_AVR.c
Created: 4/18/2018 7:55:07 PM
Author :
*/
#define F_CPU 16000000
#define BAUD 9600
#define TUBRR (((F_CPU / 16) / BAUD) - 1)
#include <avr/io.h>
#include <util/delay.h>
char Read;
void USART_Init(void){
UBRRL = TUBRR;
UCSRB = (1<<TXEN)|(1<<RXEN);
UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
}
char USART_Receive(void){
/* Wait for data to be received */
while (!(UCSRA & (1<<RXC)));
/* Get and return received data from buffer */
return UDR;
}
int main(void){
USART_Init();
DDRB |= (1<<0);
PORTB |= (1<<0);
while (1){
Read = USART_Receive();
if(Read == 'F'){
PORTB ^= (1<<0);
_delay_ms(100);
}
}
}
I'm trying to toggle an LED when I receive a certain character through the Bluetooth module (HC05).
I've written the USART library just like the datasheet but it doesn't seem to work (I'm only concerned with the initialization and receiving code since I'm working on a half duplex system so i don't need the transmition part).
I'm using Atmega32a with a 16MHz external crystal Oscillator.
Please tell me if you find anything wrong.
Thanks in advance.
Your Initialization is wrong.
Try this
void USART_Init(void){
UBRRL = TUBRR;
UBRRH = TUBRR >> 8;
UCSRB = (1<<TXEN)|(1<<RXEN);
UCSRC = (1<<UCSZ1)|(3<<UCSZ0);
}
This is the following initialization code provided in data sheet of atmega32
void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}
I know following datasheet is little overhead in beginning But eventually you will see all your answers are provided there.

setting an i2c register to high

I have this project that my boss asked me to do and the first step is to figure out how to set a given I2C register to high or low using the silicon lab library, if anyone knows any good sources for this type of problem please provide them thank you. The pic that I am using is the pic16f1823, I've already looked at the documentation of the pic but into only states how to read and write to an I2c.
I use this as a header file and seems to work well for PIC16F1827 which is basically the same as the 1823. It used the peripheral of the PIC. Just include in in any c file you want to use i2c in. Make sure you #define FOSC in order to calculate the correct baud rate. Also double check the port and tris assignments are correct for your device and make adjustments.
It uses polling instead of an interrupt. Uncomment the interrupt setup code and write an interrupt service routine to catch the interrupts.
#ifndef I2C_H
#define I2C_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Hi-Tech C I2C library for 12F1822
* Master mode routines for I2C MSSP port to read and write to slave device
* Copyright (C)2011 HobbyTronics.co.uk 2011
* Freely distributable.
*/
#define I2C_WRITE 0
#define I2C_READ 1
// Initialise MSSP port. (12F1822 - other devices may differ)
void i2c_Init(void){
// Initialise I2C MSSP
// Master 100KHz
TRISB2 = 1;
TRISB5 = 1;
SSP1CON1 = 0b00101000; // I2C Master mode
SSP1CON2 = 0b00000000;
SSP1CON3 = 0b00000000;
//SSP1MSK = 0b00000000;
SSP1ADD = I2C_BRG; // clock = FOSC/(4 * (SSPxADD+1))
//SSP1IE = 1; // enable interrupt
SSP1STAT = 0b10000000;
}
// i2c_Wait - wait for I2C transfer to finish
void i2c_Wait(void){
while ( ( SSP1CON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );
}
// i2c_Start - Start I2C communication
void i2c_Start(void)
{
i2c_Wait();
SSP1CON2bits.SEN=1;
}
// i2c_Restart - Re-Start I2C communication
void i2c_Restart(void){
i2c_Wait();
SSP1CON2bits.RSEN=1;
}
// i2c_Stop - Stop I2C communication
void i2c_Stop(void)
{
i2c_Wait();
SSP1CON2bits.PEN=1;
}
// i2c_Write - Sends one byte of data
void i2c_Write(unsigned char data)
{
i2c_Wait();
SSPBUF = data;
}
// i2c_Address - Sends Slave Address and Read/Write mode
// mode is either I2C_WRITE or I2C_READ
void i2c_Address(unsigned char address, unsigned char mode)
{
unsigned char l_address;
l_address=address<<1;
l_address+=mode;
i2c_Wait();
SSPBUF = l_address;
}
// i2c_Read - Reads a byte from Slave device
unsigned char i2c_Read(unsigned char ack)
{
// Read data from slave
// ack should be 1 if there is going to be more data read
// ack should be 0 if this is the last byte of data read
unsigned char i2cReadData;
i2c_Wait();
SSP1CON2bits.RCEN=1;
i2c_Wait();
i2cReadData = SSPBUF;
i2c_Wait();
if ( ack ) SSP1CON2bits.ACKDT=0; // Ack
else SSP1CON2bits.ACKDT=1; // NAck
SSP1CON2bits.ACKEN=1; // send acknowledge sequence
return( i2cReadData );
}
#ifdef __cplusplus
}
#endif
#endif /* I2C_H */
Then you can use the higher level functions defined above to control a device, which is described in the datasheet of the slave device.
For example, to read from an eeprom:
#include <xc.h>
#define FOSC 16000000
#include "i2c.h"
unsigned char i2c_read_eeprom( unsigned char slaveaddress, unsigned char memaddress )
{
unsigned char data;
data = 123;
i2c_Start();
i2c_Address( slaveaddress, I2C_WRITE);
i2c_Write(memaddress);
if( SSP1CON2bits.ACKSTAT )
txstring("ACK!\r\n");
else txstring("nACK!\r\n");
i2c_Start();
i2c_Address( slaveaddress, I2C_READ);
data = i2c_Read(0);
i2c_Stop();
return data;
}

PIC to PIC UART communication to Blink the LED

I want to send a command by PIC12F1572 to another PIC12F1572 through UART
and in that I want to send a function which will blink the LED on the slave PIC.
I have done some code but I am somewhat confusing
can anyone help me here?
P.S- I am Using MPLAB X IDE v3.50
Master/Transmitter PIC12F1572:
#include <xc.h>
#include "main.h"
#include "config.h"
#include "TYPEDEF_Definitions.h"
#include "PIC_12_Timer0.h"
#include "PIC_12_UART.h"
#include "System_init.h"
#include "Pin_manager.h"
#include "LED.h"
#define _XTAL_FREQ 16000000
void main()
{
SYSTEM_Initialize();
//pin_config();
LATA = 0x00;
UART_Init(); //Initialize UART
// StartLedBlinkingWithColor(color);
TRISAbits.TRISA2 = 1; //make RA2 as input
while (1)
{
//LATAbits.LATA2 = 1;
uint8_t Var = 0x61;
//uint8_t Var = LATAbits.LATA2;
if(TXSTAbits.TRMT == 1)
{
UART_write(LED_Blink()); // is it possible?? or how it will be possible
// __delay_ms(1000);
}
LATAbits.LATA2 = 1;
}
}
void LED_Blink()
{
LATAbits.LATA2 = 1;
LATAbits.LATA5 = 1;
__delay_ms(1000);
LATAbits.LATA2 = 0;
LATAbits.LATA5 = 0;
}
RECEIVER/SLAVE PIC12F1572:
#include <xc.h>
#include "config.h"
#include "PIC_12F_GPIO.h"
#include "Led.h"
#include "Interruptmanage.h"
#include "PIC_12F_UART.h"
#include "PIC_12F_TIMER0.h"
#include "main.h"
void main( void)
{
uint8 data;
InterruptInit();
TIMER0_Init();
UART_Init();
InitLeds(); // here I init GPIO pin..no prb here
// SetLedOff();
/*-------------R E C E I V E R*------------*/
while (1)
{ // Endless loop
if (UART_DataReady() ) // I get prob here ..
{
PORTA = UART_ReadOneByte(); // read the received data, [how can I receive my Led_Blink() function??
LATAbits.LATA2 = 1;
//LATAbits.LATA2 = data;
//SendByteSerially(data);
}
}
}
There are a couple of things to consider:
You cannot "send a function" through the UART. Therefore, the LED_Blink() function needs to be on the receiver side. Before doing anything else, verify that the function works on the receiver side, without any UART interaction.
Next, you can define a protocol, which is basically deciding which byte values you send through the UART should trigger the LED_Blink() call on the receiver side. For example, if you decide to use the byte value of 42 to trigger a LED blink, your sender would call UART_write(42) and on the receiver side, you would have something like the following:
data = UART_ReadOneByte();
if (data == 42) {
LED_Blink();
}
So for Receiving data from UART and saving it in array and use the data to vlink nthe LED I Have done this code: Anyone interested can have a look
while (1)
{
if (EUSART_DataReady)
{
for (i = 0; i<FRAMESIZE; i++) //#define FRAMESIZE 19
{
RX_Buffer[i] = EUSART_Read();
if (RX_Buffer[i] == '\n') //check'\n' in the end of frame
break;
}
RX_Buffer[i] = '\n'; //append '\n' at the end of stoaring array for detection of frame
RX_Buffer[i+1] = '\0'; // End of an array
EUSART_WriteAnArrayOfBytes(RX_Buffer);
if(RX_Buffer[0]=='R' && RX_Buffer[FRAMESIZE-2] == '\n') //check for correct frame
{
LATAbits.LATA2 = 1;
__delay_ms(2000);
LATAbits.LATA2 = 0;
__delay_ms(1000);
}
}
}

Need to read analog input to a pic16f688 using mplab and xc8 compiler

I am using a PIC16f688 to try to read analog input and to turn a light on or off based on the voltage read. Using this PIC, I have successfully gotten the light to blink using on and off. Here is the code I used for that.
void main() {
ANSEL = 0b00000000; //All I/O pins are configured as digital
CMCON0 = 0x07; // Disbale comparators
TRISC = 0b00000000; // PORTC All Outputs
TRISA = 0b00001000; // PORTA All Outputs, Except RA3
do {
RC0 = 1;
__delay_ms(500);
RC0 = 0;
__delay_ms(500);
} while (1); // Infinite Loop
}
After reading different things I ended up with this code to try to read the analog input.
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#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 CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#include <xc.h>
#include <pic16f688.h>
#define _XTAL_FREQ 8000000
void main() {
int voltage;
ANSEL = 0b01000000; //All I/O pins are configured as digital except an6/RC2
TRISC = 0b00000100; // PORTC All Outputs except RC2
TRISA = 0b00001000; // PORTA All Outputs, Except RA3
do {
ADCON0 = 0xbb; //set to read
GO_nDONE = 1;
while(GO_nDONE == 1);
voltage = (ADRESH << 8) + ADRESL; //get voltage reading
if(voltage > 500){ //if voltage is greater than 500 out of 1023 turn light on
RC0 = 1;
}
else{
RC0 = 0;
}
__delay_ms(500);
} while (1); // Infinite Loop
}
When I run this, the light is on no matter what the input is, including when the input is wired to ground.
I am using XC8 compiler in MPLab.
I hope that you are using external oscillator otherwise you have set wrong internal oscillator!
Default ADC clock is Fosc/2 and is to high for 8Mhz, so set the ADCON1 to Fosc/16 check datasheet.
Why did you remove this line?
CMCON0 = 0x07; // Disbale comparators
It is essential!
Try disabling the comparators using CMCON0 = 0x07; then RC0 should function normally.

Resources