Pic16f877a lcd code not working - pic

i have been recently learning microcontroller and now I am trying to make an LCD program with MPLAB X ide and XC8 but in the hard way using no libraries of XC8 but it is not working at all here are all the details:
Components:
LCD LM016L
Microcontroller pic16f877a
Pin connections:
Register select pin --> pin E0, Read/Write pin --> pin E1, Register Select pin --> pin E2
Data lines (8 bits mode) port D.
Now this is the whole code:
#include "config.h"
//port E pin 0 --> RS, pin 1 --> R/W, pin 2 --> En
#define RS TRISE0
#define RW TRISE1
#define EN TRISE2
void blinkEnable(void);
void check_if_busy(void);
void send_a_command(int command);
void send_a_character(int character);
void main(){
blinkEnable();
__delay_ms(10);
check_if_busy();
__delay_ms(10);
send_a_command(0x01);
__delay_ms(10);
send_a_character(0x46);
while(1){
}
}
void blinkEnable(){
TRISEbits.EN = 1;
__delay_ms(10);
TRISEbits.EN = 0;
__delay_ms(10);
}
void check_if_busy(){
TRISEbits.RS = 0;
TRISEbits.RW = 1;
TRISDbits.TRISD7 = 1;
while(PORTDbits.RD7 == 1){
}
}
void send_a_command(int command){
TRISEbits.RW = 0;
TRISEbits.RS = 0;
PORTD = command;
}
void send_a_character(int character){
TRISEbits.RW = 0;
TRISEbits.RS = 1;
PORTD = character;
}

If you are beginner to microchip microcontroller, I recommend you to try flowcode software developed by Matrix Multimedia which provides graphical programming environment where you just have to place blocks to access modules (say LCD module in your case) instead of writing code (flowcode will write code for you and you just have to give inputs and get output ). Best part is , you can see c code for every block you have used which gives a clear idea for beginners what program should me written to access different modules and another best part is, you can simulate entire code on the flowcode software before running on the hardware and flowcode has got one of the best compiler for microchip microcontrollers..

You can use the XC8 library by electroSome. You can download the library header file from their website and include it in your project. It is very easy.
Use this link :
Interfacing LCD with with PIC Microcontroller - MPLAB XC8

Though it is a good practice of making your own functions, but I suggest you to use already compiled and tested libraries to save your time and effort, also you can use MikroC compiler that already has bunch of software libraries available, and it is much easier to understand.

Related

HLS: How to separate AXI4 signals

I am trying to write a module that uses the AXI4 streaming protocol to communicate with the previous and next modules. The modules use the following communication signals:
TDATA, which is 16 bits,
TKEEP, which is 2 bits,
TUSER, which is 1 bit,
TVALID, which is 1 bit,
TREADY, which is 1 bit and goes towards the previous module, and
TLAST, which is 1 bit.
These all need to be separate signals. I tried to implement it using the following code:
#include "core.h"
void core_module(hls::stream<ap_axis_str> &input_stream, hls::stream<ap_axis_str> &output_stream){
#pragma HLS INTERFACE axis port=input_stream
#pragma HLS INTERFACE axis port=output_stream
#pragma HLS INTERFACE s_axilite port=return bundle=CTRL
ap_axis_str strm_val_in;
ap_axis_str strm_val_out;
for (int i = 0; i<NDATA; i++){
strm_val_in = input_stream.read();
strm_val_out.data = strm_val_in.data * 2;
strm_val_out.keep = 3;
strm_val_out.valid = 1;
strm_val_in.ready = 1;
strm_val_out.user = ((i%2)==0);
strm_val_out.last = (i == NDATA-1) ? 1:0;
output_stream.write(strm_val_out);
}
}
where the header file is
#ifndef core_h
#define core_h
#include <ap_int.h>
#include <ap_axi_sdata.h>
#include <hls_stream.h>
typedef ap_uint<16> word;
#define NDATA 10
struct ap_axis_str {
word data;
ap_uint<2> keep;
bool user;
bool last;
bool ready;
bool valid;
};
void core_module(hls::stream<ap_axis_str> &input_stream, hls::stream<ap_axis_str> &output_stream);
#endif
The problem is that this doesn't separate the signals. When I synthesise it and run it in the co-simulation (giving it values from 0 to 9), even if the result is what I expect it to be, the waveform produced looks like this:
We can see that TREADY, TVALID, and TDATA are there, but not the other 3. Furthermore, looking at the contents of TDATA (which for some reason are 64 bits) we notice that they contain all the signals. They are the following:
0001000001030000,
0001000000030002,
0001000001030004,
0001000000030006,
...
000100000003000c, (they are in base 16)
0001000001030010,
0001000100030012.
From which we can see that the 3 in position 12 is probably what was intended to be TKEEP, the 1 in position 8 which only appears in the last case is probably what was intended to be TUSER, the last 4 digits are what was supposed to be TDATA, etc. Additionally, the program drops TREADY when it isn't ready to receive data, which is what is intended of TREADY, but I didn't program it to work this way, which means that it's automatically generated and probably has nothing to do with the TREADY I told it to have.
So my question is: How do I make a module that gives out the correct 6 separate signals for the version of the AXI4 protocol that we are using?
Well, according to the Xilinx Documentation,
If you specify an hls::stream object with a data type other than ap_axis or ap_axiu, the tool will infer an AXI4-Stream interface without the TLAST signal, or any of the side-channel signals. This implementation of the AXI4-Stream interface consumes fewer device resources, but offers no visibility into when the stream is ending.
Now I had already imported the needed module with#include <ap_axi_sdata.h>, all I needed to do was actually use it by removing
struct ap_axis_str {
word data;
ap_uint<2> keep;
bool user;
bool last;
bool ready;
bool valid;
};
and replacing it with
typedef ap_axiu<16, 1, 0, 0> ap_axis_str;
Additionally, I needed to remove my manual attempt to control TREADY and TVALID, as those are done automatically.

use RNG library in stm32f4xx

I want to write simple code to generate random number with built-in hardware in stm32f4xx discovery board. I wrote the code below but it does not work. It sticks in inner while loop and the flag never set to jump out of loop.
#include <stm32f4xx.h>
#include <stm32f4xx_rng.h>
#include <stm32f4xx_rcc.h>
void RNG_Config(void)
{
/* Enable RNG clock source */
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
/* RNG Peripheral enable */
RNG_Cmd(ENABLE);
}
int main(void)
{
uint32_t temp = 0;
RNG_Config();
while(1)
{
while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET);
temp = RNG_GetRandomNumber();
}
}
Simply study STMicroelectronics examples at
STM32CubeH7-master\Projects\NUCLEO-H743ZI\Examples\RNG\RNG_MultiRNG
The code can be download from github. Google search STM32CubeH7-master and github
I have solved this problem myself by adding SystemInit() in the beginning of main function.

Processor has been reset by watch dog timer (PIC16F72, XC8 compiler)

I have started PIC programming for PIC16F72 micro-controller through MPLAB X IDE and XC8 compiler.Below is my code, it is compiled successfully.
#define _XTAL_FREQ 4000000
#include<xc.h>
#pragma config FOSC = RC // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
char pattern[] = {0b10000001,0b11000011,0b11100111,0b11111111,0b11100111,0b11000011,0b10000001};
void write(char tab)
{
char check;
for(int a=0;a<8;a++)
{
check = ((tab >> a) & 1);
if(check)
{
PORTBbits.RB7=1;
PORTBbits.RB6=0;PORTBbits.RB6=1;
}
else
{
PORTBbits.RB7=0;
PORTBbits.RB6=0;PORTBbits.RB6=1;
}
}
}
void main(void) {
TRISB=0x00; //Initialize as output
PORTBbits.RB6=0;
PORTBbits.RB5=0;
PORTBbits.RB5=1;
while(1)
{
for(int i=0;i<7;i++)
{
write(pattern[i]);
__delay_ms(1000);
}
}
return;
}
When I simulated my code in Proteus it shows below error
Processor has been reset by watch dog timer expiring at xxxxx after every 2.3 seconds.
I have searched for this problem with no success. I am unable to resolve the issue
you forget a letter. You have...
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
it should be
#pragma config WDTEN = OFF
Check out page 60 of the datasheet
Try with
__CONFIG(_WDT_OFF & _PWRTE_ON)
Instead of using #pragma config
You can try to use MPLAB X to generate configuration bits for you.
In MPLAB X, click Window -> PIC Memory Views -> Configuration Bits. New window will show up where you can configure your PIC and disable watchdog. If you click button "Generate Source Code to Output" MPLAB will generate source code with proper Configuration Bits for PIC you're using in project. Here's official Microchip tutorial which describes it in detail -http://microchipdeveloper.com/mplabx:view-and-set-configuration-bits
Proteus, the simulation tool, is not officially provided by microchip (chip manufacturer), also sometimes the pirated copy of software creates issues, one thing you can try is double click on the microcontroller in Proteus and change the configuration word to what you actually want. I suggest you to test the code on physical microcontroller.

Control relay from PIC18 microchip

I have a PIC18F24K20 microchip, and wants to control a relay. It works fine from my RasPI over GPIO - but i cant get it working trough my microchip.
My test program is this:
#include <xc.h>
#define R1 LATBbits.LATB0
#define R1_TRIS TRISBbits.RB0
#define R2 LATBbits.LATB1
#define R2_TRIS TRISBbits.RB1
void main(void) {
R1_TRIS = 0;
R2_TRIS = 0;
R1 = 1;
R2 = 0;
return;
}
What is im doing wrong?
replace the return;
with:
while(1)
{
ClrWdt();
}
according datasheet,RB0 and RB1 have several modules connected to these pins,so you should verify they are turned off:
Analog,
ECCP,
Comparator.
BTW why using two pins in order to control one relay?
3.you may need add driver in order to operat the relay.
according datasheet, add following initialization code:
CCP1CON=0;
CCP2CON=0;
ADCON0=0;
CM1CON0=0;
CM2CON0=0;
also PBADEN bit at configuration bit should be zero.
The main function should never return in the embedded PIC processors. In some implementations, it would cause a software reset which would cause your pins to go back to high impedance mode. Try adding while (1); at the end of your main.
Check if the used pins have other functions. The typical gotcha is that the pins double as analog pins and are enable by default.
Disable them by looking up which AN pin they correspond to in the datasheet and disable them with code like
ANSEL.ANS0 = 0;
ANSEL.ANS1 = 0;
If you enable watchdog functionality you also might want to add a
ClrWdt();
to the main WHILE loop (which was a good suggestion from Mathieu)

What happens with errors on Arduino during runtime?

If using Arduino, what would it do if I used code like this:
int status;
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
digitalWrite(13, status);
}
What would thiscode do? Would the LED turn on? Would it damage the chip? When compiling in the Arduino IDE, it said it was fine. There are other issues that the compiler won't catch, but what will they do? One other example is doing "digitalRead();" while it is set as an output.
Note: Using Arduino Uno SMD edition R2.
You will not damage the Arduino, but you cannot be sure about the output, since the value is not initialized. It holds whatever value the memory holds in its location (think of it as an unknown random value). Most probably though, it will be turned on, because digitalWrite sets the pin to high if you pass anything other than LOW (=0) to it. Look at Arduino's source code in wiring_digital.c:
if (val == LOW) {
*out &= ~bit;
} else {
*out |= bit;
}
Regarding your other questions:
Reading a pin value returns PINx register value, which is the physical state (high or low) of the pin, regardless of its mode (in or out).
In general, it is really difficult to damage Arduino, and in most cases you need to apply some high/negative voltage on some pins to damage it.

Resources