I am a beginner at MCU. I just turned on an LED, and RGB LED. And I will talk about my project briefly:
By using DHT11 Temp. Sensor with MSP430G2553 MCU, LED strip (which I have ws2812b contains 60led on a 1-meter strip) must change its color gradually. Like if the room temp. is 0, LED strip must be blue, but when the room/environment gets hotter, the color has to change gradually to the color red. But it must be like this: blue-> blueish-> reddish-> red.
As I stated before, I am truly a beginner. I did lots of research but all done with Arduino or with different components. I used a code to calculate the temperature by Dr.Selim's youtube channel about DHT11. But I couldn't use th (temperature high) for changing led colors. I truly need help with the code.
Here is what've I tried unskillfully by trying to get 2 different codes work in charm together but have failed.
#include <msp430.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ws2812.h"
volatile int temp[50];
volatile int diff[50];
volatile unsigned int i=0;
volatile unsigned int j=0;
char th_char[5];
char tl_char[5];
char hh_char[5];
char hl_char[5];
volatile int hh = 0;
volatile int hl = 0;
volatile int th = 0;
volatile int tl = 0;
volatile int check = 0;
volatile int checksum = 0;
volatile int dataok;
char temperature[] = "Temperature is: ";
char dot[] = ".";
char celcius[] = " degrees Celcius ";
char humidity[] = "Humidity is: ";
char percent[] = " %\r\n";
void ser_output(char *str);
void main(void);
void gradualFill(u_int n, u_char r, u_char g, u_char b)
int main(void)
{
WDTCTL = WDTPW | WDTHOLD;
BCSCTL1= CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
P1SEL = BIT1|BIT2;
P1SEL2 = BIT1|BIT2;
UCA0CTL1 |= UCSWRST+UCSSEL_2;
UCA0BR0 = 52;
UCA0BR1 = 0;
UCA0MCTL = UCBRS_0;
UCA0CTL1 &= ~UCSWRST;
__delay_cycles(2000000);
P2DIR |= BIT4;
P2OUT &= ~BIT4;
__delay_cycles(20000);
P2OUT |= BIT4;
__delay_cycles(20);
P2DIR &= ~BIT4;
P2SEL |= BIT4;
TA1CTL = TASSEL_2|MC_2 ;
TA1CCTL2 = CAP | CCIE | CCIS_0 | CM_2 | SCS ;
_enable_interrupts();
while (1){
if (i>=40){
for (j = 1; j <= 8; j++){
if (diff[j] >= 110)
hh |= (0x01 << (8-j));
}
for (j = 9; j <= 16; j++){
if (diff[j] >= 110)
hl |= (0x01 << (16-j));
}
for (j = 17; j <= 24; j++){
if (diff[j] >= 110)
th |= (0x01 << (24-j));
}
for (j = 25; j <= 32; j++){
if (diff[j] >= 110)
tl |= (0x01 << (32-j));
}
for (j = 33; j<=40; j++){
if (diff[j] >= 110)
checksum |= (0x01 << (40-j));
}
check=hh+hl+th+tl;
if (check == checksum)
dataok = 1;
else
dataok = 0;
//if you get an error with ltoa, try: 'ltoa(th,th_char,10)'
//check article:
//https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_handling_changes_in_ltoa.html
ltoa(th,th_char, 10);
ltoa(tl,tl_char, 10);
ltoa(hh,hh_char, 10);
ltoa(hl,hl_char, 10);
ser_output(temperature); ser_output(th_char); ser_output(dot); ser_output(tl_char); ser_output(celcius);
ser_output(humidity); ser_output(hh_char); ser_output(dot); ser_output(hl_char); ser_output(percent);
__delay_cycles(1000000);
WDTCTL = WDT_MRST_0_064;
}
if (CALBC1_16MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
// configure clock to 16 MHz
BCSCTL1 = CALBC1_16MHZ; // DCO = 16 MHz
DCOCTL = CALDCO_16MHZ;
// initialize LED strip
initStrip();
while (1) {
gradualFill(NUM_LEDS, 0x00, 0xFF, 0x00); // green
gradualFill(NUM_LEDS, 0x00, 0x00, 0xFF); // blue
gradualFill(NUM_LEDS, 0xFF, 0x00, 0xFF); // magenta
gradualFill(NUM_LEDS, 0xFF, 0xFF, 0x00); // yellow
gradualFill(NUM_LEDS, 0x00, 0xFF, 0xFF); // cyan
gradualFill(NUM_LEDS, 0xFF, 0x00, 0x00); // red
}
}
}
void gradualFill(u_int n, u_char r, u_char g, u_char b){
int th;
for (th = 0; i < n; th++){ // n is number of LEDs
setLEDColor(th, r, g, b);
showStrip();
_delay_cycles(1000000); // lazy delay
}
}
#pragma vector = TIMER1_A1_VECTOR
__interrupt void Timer_A1(void){
temp[i] = TA1CCR2;
i += 1;
TA1CCTL2 &= ~CCIFG ;
if (i>=2) diff[i-1]=temp[i-1]-temp[i-2];
void ser_output(char *str){
while(*str != 0){
while (!(IFG2&UCA0TXIFG));
UCA0TXBUF = *str++;
}
}
Related
Using MSP430F6736A embedded programming. Code written in Code Composer Studio. I have a problem in my code, but i have no idea what i can do to fix it.
When I compile the program in code composer, works well but UART are sending to PC just ".ø€.ø€.€€x" that means i'm getting only strange charracters
#include "msp430g2553.h"
#include <stdio.h>
float RLDR=0, lux=0, v0=0;
unsigned int ADC10_vetor[16]={0};
unsigned int sum=0;
unsigned char i=0;
unsigned char TX_data[32], tx_index = 0, lux_int =0;
void ini_ucon(void);
void ini_p1_p2(void);
void ini_Timer0(void);
void ini_ADC10(void);
void ini_USCI_UART(void);
void ini_ucon(void){
WDTCTL = WDTPW | WDTHOLD;
DCOCTL = CALDCO_8MHZ;
BCSCTL1 = CALBC1_8MHZ;
BCSCTL2 = DIVS0 + DIVS1; //SMCLK = 1MHz
__enable_interrupt();
}
void ini_p1_p2(void){
P1DIR = 0xFF;
P1OUT = 0x00;
P2DIR = 0xFF;
P2OUT = 0x00;
}
void ini_Timer0(void){
TA0CTL = TASSEL1 + ID1 + ID0 + MC0; //SMCLK = 1MHz/8 = 125000
TA0CCTL1 = OUTMOD0 + OUTMOD1 + OUTMOD2 + OUT;
TA0CCR0 = 62499; //2Hz = 0.5 secs. , TA0CCR0 = 0.5*125000 - 1 = 62499
TA0CCR1 = 31249; //PWM = 50%
}
void ini_ADC10(void){
ADC10CTL0 = ADC10SHT1 + MSC + ADC10ON + ADC10IE;
ADC10CTL1 = INCH0 + INCH2 + SHS0 + ADC10SSEL1 + CONSEQ1;
ADC10AE0 = BIT5; //P1.5 para A5
ADC10DTC0 = 0;
ADC10DTC1 = 16;
ADC10SA = &ADC10_vetor[0];
ADC10CTL0 |= ENC;
}
int main(void){
ini_ucon();
ini_p1_p2();
ini_Timer0();
ini_ADC10();
ini_USCI_UART();
while(1){
}
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_RTI(void){
ADC10CTL0 &= ~ENC;
soma = 0;
for(i=0;i<16;i++){
sum = sum + ADC10_vetor[i];
}
sum = sum >> 4;
//RLDR = (42625000)/(3*sum)-10000;
//lux = 500/(RLDR/1000);
//v0=5*(sum/(sum+10000));
v0=sum*(3.6/1024);
RLDR = (10000*(5-v0))/v0;
lux = (500/(RLDR/1000));
lux_int = (unsigned char) lux;
sprintf(&TX_data[0], "LUX = %d \n", lux_int);
UCA0TXBUF = TX_data[0];
tx_index++;
ADC10SA = &ADC10_vetor[0];
ADC10CTL0 |= ENC;
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void RTI_USCI_UART(void)
{
IFG2 &= ~UCA0TXIFG;
if(TX_data[tx_index] == '\0'){
tx_index = 0;
}else{
if(tx_index >= 32){
tx_index = 0;
}else{
UCA0TXBUF = TX_data[tx_index];
tx_index++;
}
}
}
void ini_USCI_UART(void){
UCA0CTL1 |= UCSWRST;
UCA0CTL0 = 0;
UCA0CTL1 = UCSSEL0 + UCSSEL1 + UCSWRST;
UCA0BR0 = 0xA0;
UCA0BR1 = 0x01;
UCA0MCTL = UCBRS1 + UCBRS2;
UCA0STAT = 0;
P1SEL |= BIT2;
P1SEL2 |= BIT2;
UCA0CTL1 &= ~UCSWRST;
IFG2 &= ~UCA0TXIFG;
IE2 |= UCA0TXIE;
}
Does anyone have an idea how to fix this?
I am making a game where you need to repeat the sequence of LEDs that light up. This sequence is set by two LEDs. To repeat the sequence, I use the joystick.
I had an idea to make two bool arrays where True will indicate the left LED, and False will indicate the right LED. The first array must contain a random sequence(True/False) that needs to be repeated. When I push to one or the other side of the joystick, I want to write to the second array, respectively, True / False and all this time compare them.
This is what I have at the moment. (AT90USB647)
#define F_CPU 2000000UL
#include <avr/io.h>
#include <stdbool.h>
int main(void) {
MCUCR |= 0x80;
MCUCR |= 0x80;
DDRA = 0xFF;
PORTF = 0x20;
bool seq2[100];
while(1)
{
uint8_t x = PINF;
if(!(x & 0x20)) {
PORTA = 0x80;
}
else if(!(x & 0x08)) {
PORTA = 0x01;
}
else {
PORTA = 0x00;
}
}
}
The main question is how do I write True or False to an array when I push the joystick?
A basic approach could be:
#define F_CPU 2000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
volatile unsigned int counter;
static unsigned char pattern_position;
static unsigned char array_position;
static unsigned char pattern[] = {
0b01010101,
0b11010101,
0b10010101
};
ISR(TIMER0_COMPA_vect)
{
counter++;
}
int main(void)
{
MCUCR |= 0x80;
DDRA = 0xFF;
PORTF = 0x20;
// Timer initialization
// Mode: CTC
// Prescaler: 1024
TCCR0A = (1<<WGM01);
TCCR0B = (1<<CS02) | (1<<CS00);
// Calculate a correct time
//
// we want 1 ms -> f_TIMER0 = 1/T = 1/(1 * 10^-3)s = 1 kHz
//
// f_CPU f_CPU 20 MHz
// f_TIMER0 = ------------- -> OCR0A = ---------------- = ------------- = ~ 20 (It is not exactly 1ms but it is ok)
// k_H * OCR0A k_H * f_TIMER0 256 * 1 kHz
//
OCR0A = 20;
TIMSK0 = (1<<OCF0A); // Enable Timer0 Overflow Compare Match interrupt
// Show the sequence that the user should input
for (unsigned char i=0; i < sizeof(pattern)/sizeof(&pattern[0]); i++)
{
for (unsigned char j=0; j < 8; j +=2)
{
// There is possible a signal missing to show the user that the next pattern occurs!
PORTA = ((pattern[i]>>(j+1))<<PINA7) | ((pattern[i]>>j)<<PINA0);
// That the user can see the patterns a delay is necessary!
_delay_ms(1000);
}
}
// Signalize that the game starts
for (unsigned char i=0; i <8; i++)
{
PORTA ^= 0x81;
_delay_ms(1000);
}
TCNT0 = 0x00;
sei();
while(1)
{
// There is possible a signal missing to trigger next pattern input to the user!!!
if(!(PINF & (1<<PINF5)))
{
PORTA |= 0x80;
}
if(!(PINF & (1<<PINF3)))
{
PORTA |= 0x01;
}
// Time is 4 seconds to match the correct pattern
if(counter >= 4000)
{
if(!((pattern[pattern_position] & (1<<array_position)) == (0x01 & PORTA)))
{
// Wrong input end of game
}
array_position++;
if(!((pattern[pattern_position] & (1<<array_position)) == (0x01 & (PORTA>>8))))
{
// Wrong input end of game
}
array_position++;
if(array_position >= 8)
{
array_position = 0;
pattern_position++;
}
if(pattern_position >= (sizeof(pattern)/sizeof(&pattern[0])))
{
// End of game reached winning!
}
counter = 0x00;
PORTA = 0x00;
TCNT0 = 0x00;
}
}
}
I´m not sure if you are exactly trying this to do and i also can not test the code on your target platform but maybe this is a rudimental approach to solve your problem...
I want to initialize an SD card manually from an Arduino Mega 2560 and read its contents.
I've read a lot of manuals explaining how to properly do it, as well as the Arduino SD library code, but I can't get it to work.
uint8_t spi_byte(uint8_t byte) {
SPDR = byte;
asm volatile("nop");
while(!(SPSR & B10000000));
uint8_t response = SPDR;
return response;
}
uint8_t sd_cmd(uint8_t cmd, uint32_t args) {
if(cmd != 0x40) while(spi_byte(0xFF) != 0xFF);
spi_byte(cmd);
int8_t c;
for(c = 3; c >= 0; --c) spi_byte(args >> (c << 3));
uint8_t crc;
if(cmd == 0x40) crc = 0x95;
else if(cmd == 0x48) crc = 0x87;
else crc = 0xFF;
spi_byte(crc);
uint8_t response;
for(c = 16; ((response = spi_byte(0xFF)) & 0x80) && c; --c);
/*if((cmd < 0x51) || (cmd > 0x59))*/ spi_byte(0xFF); //S
return response;
}
void sd_init() {
DDRB &= B11110000;
PORTB |= B0001; //set CS pull-up resistor (just-in-case)
DDRB |= B0001; //set CS to output
PORTB |= B1000; //set MISO pull-up resistor (just-in-case)
SPCR = B01010010; //no interrupt, MSB first, master, mode 0, fosc/64 (250 kHz)
SPSR &= ~1; //clear SPI double speed
DDRB |= B0110; //set SCK and MOSI to output
delayMicroseconds(200000);
uint8_t c;
cli();
for(c = 0; c < 10; ++c) spi_byte(0xFF); //synchronize clock
clb(PORTB, 0); //set CS low
uint8_t response;
uint16_t timeout = 1024;
while((response=sd_cmd(0x40, 0)) != 0x1) { //CMD0: reset card
if((!response) || (response == 0xFF)) error(3); //we don't even have a card
if(!--timeout) error(7); //timed out
}
if(sd_cmd(0x48, 0x1AA) != 1) error(1); //CMD8: make sure we are using SD v2
for(c = 0; c < 4; ++c) spi_byte(0xFF);
do {
sd_cmd(0x77, 0); //CMD55: introduce application-specific command
response = sd_cmd(0x69, 0x40000000); //ACMD41: initialize card
if(!--timeout) error(8); //timed out
} while(response != 0);
sd_cmd(0x7A, 0); //CMD58: read OCR
response = spi_byte(0xFF);
if((response & B11000000) != B11000000) error(2); //make sure we are using SDHC
for(c = 0; c < 3; ++c) spi_byte(0xFF);
stb(PORTB, 0); //set CS high
SPCR = B01010000; //fosc/4 (4 MHz)
SPSR |= 1; //set SPI double speed (8 MHz)
for(c = 0; c < 10; ++c) spi_byte(0xFF); //synchronize clock
sei();
return;
}
void sd_read(uint8_t* buffer, uint32_t block, uint8_t start2, uint8_t size2) {
/*start2 and size2 are in 2 byte units, size2 = 0 means whole block (512 B)*/
cli();
block <<= 9; //S//D
clb(PORTB, 0); //set CS low
uint8_t response;
if((response=sd_cmd(0x51, block))) { //CMD17: read single block
Serial.begin(9600); //D
Serial.println(response, HEX); //D
error(10);
}
while(spi_byte(0xFF) != 0xFE) ; //TODO: timeout error 9
uint8_t b = 0; uint8_t end = 0;
do {
if((b >= start2) && (!end)) {
*(buffer++) = spi_byte(0xFF);
*(buffer++) = spi_byte(0xFF);
--size2;
if(!size2) end = 1;
}
else {
spi_byte(0xFF);
spi_byte(0xFF);
}
++b;
} while(b); //repeat 256 times
spi_byte(0xFF); spi_byte(0xFF); //two more bytes to close
stb(PORTB, 0); //set CS high
spi_byte(0xFF);
sei();
return;
}
Some days it works perfectly, other times it just locks up at initialization time, and finally right now I'm trying to read SD card contents and it just displays 0x55AA forever. I suspect that it is a hardware problem, but I'd like to rule out the possibility that my code might be wrong. Also, I don't know why I have to multiply reading address by 512. Being this an SDHC card, I would expect addresses to be in blocks, right?
I am interfacing LM35 with Atmega8. To display digits I use 7 segment LED anode display that I connect to AVR both ends (it handles it without transistors so why not). Strange thing happens:
res value after assigning it from adc is 237 (23.7 degrees). I want to print on my display the first digit (2).
If I leave last line in the while commented out, the display first shows digit 2 correctly but after the first delay it shows 1 instead of 2. Otherwise I get correctly digit 2. Why is this happening?
#ifndef F_CPU
#define F_CPU 1000000UL
#endif // F_CPU
#include <avr/io.h>
#include <util/delay.h>
#define DELAY_IN_MS 500 /* 0.5 sec */
int numbers[] = {
0b01000000,
0b01110011,
0b00100100,
0b00100001,
0b00010011,
0b00001001,
0b00001000,
0b01100011,
0b00000000,
0b00000001,
0b11111111 // off
};
uint8_t digits[3];
void initADC()
{
ADMUX=(1<<REFS1)|(1<<REFS0);
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
}
uint16_t ReadADC(uint8_t ch)
{
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;
ADMUX|=ch;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
//Clear ADIF by writing one to it
ADCSRA|=(1<<ADIF);
return(ADC);
}
int main()
{
DDRD = 0xFF;
PORTD = 0xFF;
DDRB = 0b00000001;
PORTB = 1;
initADC();
uint16_t adc_value;
uint16_t res;
while(1)
{
adc_value = 0;
for (int i = 0; i < 250; i++)
{
adc_value += ReadADC(0);
}
adc_value=(adc_value/25)/4;
res = adc_value;
for(int j = 2; j >= 0; j--) {
digits[j] = res%10;
res /= 10;
}
uint8_t dig = digits[0];
PORTD = numbers[dig];
_delay_ms(DELAY_IN_MS);
// if following is uncommented there blinks digit two correctly
// if commented there is unblinking digit 1
PORTD = numbers[10]; // display off
}
return 0;
}
The problem was induction.
My circuit had many wires in non-soldering-field. When the display was on, there was a lot of induction going on changing resulting voltage on ADC input/LM35 output.
There is more than one solution.
1) Software: I moved ADC conversion into the interruption function. It turns of the displays, converts value from lm35 and displays digit on proper display. It happens so fast that the eye cant perceive it.
I prefer this one for now, because it makes my circuit simpler.
2) Hardware: adding L/C or R/C filter to adc pin should resolve the issue.
Full code for 1)
#ifndef F_CPU
#define F_CPU 1000000UL
#endif // F_CPU
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define DELAY_IN_MS 5000 /* ms */
#define NUM_OF_MEASUREMENTS 100
#define NUM_DISPLAYS 3
int numbers[] = {
0b10000001,
0b10011111,
0b10100100,
0b10010100,
0b10011010,
0b11010000,
0b11000000,
0b10011101,
0b10000000,
0b10010000,
0b11111111 // off
};
int display = 0;
uint8_t digits[NUM_DISPLAYS];
volatile uint16_t adc_values[NUM_OF_MEASUREMENTS];
int adc_read_cycle_index = 0;
uint32_t res;
void initADC()
{
ADMUX=(1<<REFS1)|(1<<REFS0);
ADCSRA=(1<<ADEN)|(1<<ADPS2);
}
uint16_t ReadADC(uint8_t ch)
{
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;
ADMUX|=ch;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while (ADCSRA & (1<<ADSC));
return(ADC);
}
void readDegrees()
{
adc_values[adc_read_cycle_index] = (ReadADC(0)*10)/4;
if(adc_read_cycle_index + 1 == NUM_OF_MEASUREMENTS) {
adc_read_cycle_index = 0;
} else {
adc_read_cycle_index++;
}
}
void fetchTemperatureDigits() {
res = 0;
for(int i = 0; i < NUM_OF_MEASUREMENTS; i++) {
res += adc_values[i];
}
res /= NUM_OF_MEASUREMENTS;
for(int j = 2; j >= 0; j--) {
digits[j] = res%10;
res = res / 10;
}
}
void initTimer0()
{
// Prescaler = FCPU/64
TCCR0|=(1<<CS01);//|(1<<CS00);
//Enable Overflow Interrupt Enable
TIMSK|=(1<<TOIE0);
//Initialize Counter
TCNT0=0;
}
ISR(TIMER0_OVF_vect)
{
// turn off displays
PORTD = numbers[10];
// read ADC and convert to degrees
readDegrees();
// turn on proper anode
PORTB &= 0b11111000;
PORTB |= (1<<display);
// show digit
PORTD = numbers[digits[display]];
// show decimal point for second display (21.5 - second display shows "1.")
if(display == 1) {
PORTD &= 0b01111111;
}
// next display for next interruption
display++;
if(display == NUM_DISPLAYS) {
display = 0;
}
}
int main()
{
initADC();
for(int i = 0; i < NUM_OF_MEASUREMENTS; i++) {
readDegrees();
}
DDRD = 0xFF;
PORTD = 0;
DDRB |= 0b00000111;
PORTB |= 1;
initTimer0();
sei();
while(1) {
fetchTemperatureDigits();
_delay_ms(DELAY_IN_MS);
}
return 0;
}
I have a C program that I am trying to put on my pic but I get the error "3.17 can't open include file "main.h": No such file or directory". This is my first time ever attempting to program a pic.
Here is the program I am trying to put on it.
#include <htc.h>
#include <stdio.h>
#include "main.h"
__CONFIG(FOSC_INTOSC & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF);
__CONFIG(WRT_OFF & PLLEN_OFF & STVREN_OFF & BORV_HI & LVP_OFF);
#define _XTAL_FREQ 4000000
int main()
{
int t = 0;
char outStr[8];
char ch;
init();
Lcd_PutStr(0, 0, "Option 1");
Lcd_PutStr(1, 0, "Spec Analyzer");
while (1)
{
// do stuff here
}
}
int init()
{
// Hardware
OSCCON = 0x6A; // 4 MHz oscillator
PORTA = 0; // Clear Port A
LATA = 0;
PORTB = 0; // Clear Port B
LATB = 0;
PORTC = 0; // Clear Port C
LATC = 0;
ANSELA = 0; // Set Port A to digital
ANSELB = 0; // Set Port B to digital
ANSELC = 0; // Set Port C to digital
TRISB = 0; // Set port B to output
TRISC = 0; // Set port C to output
// LCD display
Lcd_Init();
return 0;
}
void ENPulse()
{
LATC |= 0x20;
__delay_us(1);
LATC &= 0xdf;
}
void Lcd_Init()
{
LATC = 0;
__delay_ms(40);
LATC = 0x03;
ENPulse();
__delay_us(37);
Lcd_Cmd(0x28);
__delay_us(37);
Lcd_Cmd(0x28);
__delay_us(37);
Lcd_Cmd(0x0C);
__delay_ms(2);
Lcd_Cmd(0x01);
__delay_us(37);
}
void Lcd_Cmd(byte cmd)
{
LATC = cmd >> 4;
ENPulse();
LATC = cmd & 0x0F; // clear RS (LATC,4)
ENPulse();
__delay_us(100);
}
void Lcd_Data(byte data)
{
LATC = (data >> 4) | 0x10; // set RS (LATC,4)
ENPulse();
LATC = (data & 0x0F) | 0x10; // set RS (LATC,4)
ENPulse();
__delay_us(100);
}
void Lcd_PutStr(int row, int col, char* str)
{
int pos;
// use row and column=-1 for no positioning, i.e. position where last ended
if (row >= 0 && col >= 0)
{
if (row > 0)
row = 0x40; // row 1
else
row = 0; // row 0
pos = row | col | 0x80; // 0x80 is cmd for positioning cursor
Lcd_Cmd(pos);
}
while (*str)
{
Lcd_Data(*str);
str++;
}
}
I am using MPLab and Hi-Tech C with a Pickit3. I based this code off of a sample given to me. I do not know what the purpose of the main.h file is. Any help is appreciated.
After reviewing your errors, you may be able to run the code without main.h. It looks like main.h mostly prototypes the functions at the bottom of the file. Try putting this code between the main and the #define:
int init();
void ENPulse();
void Lcd_Init();
void Lcd_Cmd(byte cmd);
void Lcd_Data(byte data);
void Lcd_PutStr(int row, int col, char* str);
This should at lest reduce most of your errors. It may fix it completely. The idea is that when the compiler first encounters theses functions it doesn't know what they are and it throws errors before it can find them. If there are still errors let me know and I'll try and help more.
Try this code:
#include <htc.h>
#include <stdio.h>
//#include "main.h"
__CONFIG(FOSC_INTOSC & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF);
__CONFIG(WRT_OFF & PLLEN_OFF & STVREN_OFF & BORV_HI & LVP_OFF);
#define _XTAL_FREQ 4000000
int init()
{
// Hardware
OSCCON = 0x6A; // 4 MHz oscillator
PORTA = 0; // Clear Port A
LATA = 0;
PORTB = 0; // Clear Port B
LATB = 0;
PORTC = 0; // Clear Port C
LATC = 0;
ANSELA = 0; // Set Port A to digital
ANSELB = 0; // Set Port B to digital
ANSELC = 0; // Set Port C to digital
TRISB = 0; // Set port B to output
TRISC = 0; // Set port C to output
// LCD display
Lcd_Init();
return 0;
}
void ENPulse()
{
LATC |= 0x20;
__delay_us(1);
LATC &= 0xdf;
}
void Lcd_Init()
{
LATC = 0;
__delay_ms(40);
LATC = 0x03;
ENPulse();
__delay_us(37);
Lcd_Cmd(0x28);
__delay_us(37);
Lcd_Cmd(0x28);
__delay_us(37);
Lcd_Cmd(0x0C);
__delay_ms(2);
Lcd_Cmd(0x01);
__delay_us(37);
}
void Lcd_Cmd(byte cmd)
{
LATC = cmd >> 4;
ENPulse();
LATC = cmd & 0x0F; // clear RS (LATC,4)
ENPulse();
__delay_us(100);
}
void Lcd_Data(byte data)
{
LATC = (data >> 4) | 0x10; // set RS (LATC,4)
ENPulse();
LATC = (data & 0x0F) | 0x10; // set RS (LATC,4)
ENPulse();
__delay_us(100);
}
void Lcd_PutStr(int row, int col, char* str)
{
int pos;
// use row and column=-1 for no positioning, i.e. position where last ended
if (row >= 0 && col >= 0)
{
if (row > 0)
row = 0x40; // row 1
else
row = 0; // row 0
pos = row | col | 0x80; // 0x80 is cmd for positioning cursor
Lcd_Cmd(pos);
}
while (*str)
{
Lcd_Data(*str);
str++;
}
}
int main()
{
int t = 0;
char outStr[8];
char ch;
init();
Lcd_PutStr(0, 0, "Option 1");
Lcd_PutStr(1, 0, "Spec Analyzer");
while (1)
{
// do stuff here
}
}