LED matrix (HUB-75 type) - arduino

I'm trying to make the 64x64 LED matrix work without libraries. Started driving it with STM32F103C8T6 chip figured out the problem and tried ATmega328 instead, but nothing changed.
The problem is when I'm trying to lit a LED on specified address it actually lights up with almost 0 brightness, but the LED directly under it (on the next address) lights up with full brightness.
I cut the code to a minimum.
#define CLK 0
#define LAT 1
#define R1 2
uint16_t data [64][4];
void shiftOutLed (void);
int main () {
data [0][0] = 0x0001;
data [0][2] = 0x1800;
DDRC |= 0x0F; //pin 0 - A, pin 1 - B, pin 2 - C, pin3 - D
DDRB |= 0x03; // pin 0 - CLK, pin 1 - LAT
DDRD |= 0x04; // pin 2 - R1
while (1){
shiftOutLed ();
}
}
void shiftOutLed (void){
for (uint8_t _addr = 0; _addr < 16; _addr++){
PORTC &= 0xF0;
PORTC |= _addr;
for (uint8_t _byte = 0; _byte < 4; _byte++){
for (uint8_t _bit = 0; _bit < 16; _bit++){
if (data[_addr][_byte] & (1 << _bit)) PORTD |= (1 << R1);
else PORTD &= ~(1 << R1);
PORTB |= (1 << CLK);
PORTB &= ~(1 << CLK);
}
}
PORTB |= (1 << LAT);
PORTB &= ~(1 << LAT);
PORTD &= ~(1 << R1);
}
}
When I modify the code introducing delays while clocking and latching every bit LEDs light up in right row.

Seems like the matrix needs the address set after clocking the entire row
#define CLK 0
#define LAT 1
#define R1 2
uint16_t data [64][4];
void shiftOutLed (void);
int main () {
data [0][0] = 0x0001;
data [0][2] = 0x1800;
DDRC |= 0x0F; //pin 0 - A, pin 1 - B, pin 2 - C, pin3 - D
DDRB |= 0x03; // pin 0 - CLK, pin 1 - LAT
DDRD |= 0x04; // pin 2 - R1
while (1){
shiftOutLed ();
}
}
void shiftOutLed (void){
for (uint8_t _addr = 0; _addr < 16; _addr++){
PORTC &= 0xF0;
for (uint8_t _byte = 0; _byte < 4; _byte++){
for (uint8_t _bit = 0; _bit < 16; _bit++){
if (data[_addr][_byte] & (1 << _bit)) PORTD |= (1 << R1);
else PORTD &= ~(1 << R1);
PORTB |= (1 << CLK);
PORTB &= ~(1 << CLK);
}
}
PORTC |= _addr;
PORTB |= (1 << LAT);
PORTB &= ~(1 << LAT);
PORTD &= ~(1 << R1);
}
}
Now it works

Related

Reading temperature values from TMP117 sensor using MSP430FR5969 MCU

I'm trying to read temperature values from the TMP117 sensor [1] connected to an MSP430FR5969 MCU [2] through the I2C protocol. The data in the result register of the sensor is in two's complement format, has a data width of 16 bits, and a resolution of 0.0078125 °C. I used Code Composer Studio to program the MCU and I've attached the code below:
#include <msp430.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#define SLAVE_ADDR 0x48
#define CONVERSION_READY 0x10
#define TMP117_TEMP_REG 0x00
#define TMP117_CONFIG_REG 0x01
#define TMP117_RESOLUTION 0.0078125f
#define CMD_TYPE_0_SLAVE 0
#define CMD_TYPE_1_SLAVE 1
#define CMD_TYPE_2_SLAVE 2
#define CMD_TYPE_0_MASTER 3
#define CMD_TYPE_1_MASTER 4
#define CMD_TYPE_2_MASTER 5
#define TYPE_0_LENGTH 1
#define TYPE_1_LENGTH 2
#define TYPE_2_LENGTH 6
#define MAX_BUFFER_SIZE 20
char temperature[] = "Temperature is: ";
char dot[] = ".";
char celcuis[] = " degree Celcius\r\n";
int i;
char text[] = " I am an MSP430FR5969\r\n";
char rx_char[5];
volatile int rx_val = 0;
void clockSetup();
void gpioSetup();
void uartSetup();
void i2cSetup();
void ser_output(char *str);
uint8_t MasterType1 [TYPE_1_LENGTH] = {0x02, 0x20};
uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
typedef enum I2C_ModeEnum{
IDLE_MODE,
NACK_MODE,
TX_REG_ADDRESS_MODE,
RX_REG_ADDRESS_MODE,
TX_DATA_MODE,
RX_DATA_MODE,
SWITCH_TO_RX_MODE,
SWITHC_TO_TX_MODE,
TIMEOUT_MODE
} I2C_Mode;
I2C_Mode MasterMode = IDLE_MODE;
/* The Register Address/Command to use*/
uint8_t TransmitRegAddr = 0;
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;
I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
RXByteCtr = count;
TXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
UCB0I2CSA = dev_addr;
UCB0IFG &= ~(UCTXIFG + UCRXIFG);
UCB0IE &= ~UCRXIE;
UCB0IE |= UCTXIE;
UCB0CTLW0 |= UCTR + UCTXSTT;
__bis_SR_register(LPM0_bits + GIE);
return MasterMode;
}
I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
CopyArray(reg_data, TransmitBuffer, count);
TXByteCtr = count;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
UCB0I2CSA = dev_addr;
UCB0IFG &= ~(UCTXIFG + UCRXIFG);
UCB0IE &= ~UCRXIE;
UCB0IE |= UCTXIE;
UCB0CTLW0 |= UCTR + UCTXSTT;
__bis_SR_register(LPM0_bits + GIE);
return MasterMode;
}
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
uint8_t copyIndex = 0;
for (copyIndex = 0; copyIndex < count; copyIndex++)
{
dest[copyIndex] = source[copyIndex];
}
}
void main(void)
{
WDTCTL = WDTPW | WDTHOLD;
clockSetup();
gpioSetup();
uartSetup();
i2cSetup();
__bis_SR_register(GIE);
while (1)
{
_delay_cycles(500000);
I2C_Master_ReadReg(SLAVE_ADDR, 0x00, TYPE_1_LENGTH);
CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH);
if(ReceiveBuffer[1] & CONVERSION_READY)
{
I2C_Master_ReadReg(SLAVE_ADDR, 0x00, TYPE_1_LENGTH);
CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH);
_no_operation();
}
ltoa(rx_val, rx_char, 10);
ser_output(temperature);
ser_output(rx_char);
ser_output(dot);
ser_output(celcuis);
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
//Must read from UCB0RXBUF
//// uint8_t rx_val = 0;
switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: break; // Vector 0: No interrupts
case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG
case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG
break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3
case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3
case USCI_I2C_UCRXIFG2: break; // Vector 14: RXIFG2
case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2
case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1
case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1
case USCI_I2C_UCRXIFG0: // Vector 22: RXIFG0
rx_val = UCB0RXBUF;
if (RXByteCtr)
{
ReceiveBuffer[ReceiveIndex++] = rx_val;
RXByteCtr--;
}
if (RXByteCtr == 1)
{
UCB0CTLW0 |= UCTXSTP;
}
else if (RXByteCtr == 0)
{
UCB0IE &= ~UCRXIE;
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0
switch (MasterMode)
{
case TX_REG_ADDRESS_MODE:
UCB0TXBUF = TransmitRegAddr;
if (RXByteCtr)
MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now
else
MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer
break;
case SWITCH_TO_RX_MODE:
UCB0IE |= UCRXIE; // Enable RX interrupt
UCB0IE &= ~UCTXIE; // Disable TX interrupt
UCB0CTLW0 &= ~UCTR; // Switch to receiver
MasterMode = RX_DATA_MODE; // State state is to receive data
UCB0CTLW0 |= UCTXSTT; // Send repeated start
if (RXByteCtr == 1)
{
//Must send stop since this is the N-1 byte
while((UCB0CTLW0 & UCTXSTT));
UCB0CTLW0 |= UCTXSTP; // Send stop condition
}
break;
case TX_DATA_MODE:
if (TXByteCtr)
{
UCB0TXBUF = TransmitBuffer[TransmitIndex++];
TXByteCtr--;
}
else
{
//Done with transmission
UCB0CTLW0 |= UCTXSTP; // Send stop condition
MasterMode = IDLE_MODE;
UCB0IE &= ~UCTXIE; // disable TX interrupt
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
default:
__no_operation();
break;
}
break;
default: break;
}
}
void ser_output(char *str)
{
while(*str !=0)
{
while(!(UCA0IFG&UCTXIFG));
UCA0TXBUF = *str++;
}
}
void gpioSetup()
{
P1OUT &= ~BIT0; // Clear P1.0 output latch
P1DIR |= BIT0; // For LED
P1SEL1 |= BIT6 | BIT7; // I2C pins
P2SEL1 |= BIT0 | BIT1; // USCI_A0 UART operation
P2SEL0 &= ~(BIT0 | BIT1);
PM5CTL0 &= ~LOCKLPM5;
}
void clockSetup()
{
FRCTL0 = FRCTLPW | NWAITS_1;
CSCTL0_H = CSKEY >> 8;
CSCTL1 = DCORSEL | DCOFSEL_0;
CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;
CSCTL0_H = 0;
}
void uartSetup()
{
UCA0CTL1 |= UCSWRST;
UCA0CTL1 |= UCSSEL_2;
UCA0BR0 = 6;
UCA0BR1 = 0;
UCA0MCTLW = 0xAA;
UCA0MCTLW |= UCOS16 | UCBRF_1;
UCA0CTL1 &= ~UCSWRST;
UCA0IE |= UCRXIE;
}
void i2cSetup()
{
UCB0CTLW0 |= UCSWRST;
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC;
UCB0CTLW1 |= UCSSEL_2;
UCB0BRW = 10;
UCB0I2CSA = 0x0048;
UCB0CTLW0 &= ~UCSWRST;
UCB0IE |= UCRXIE | UCNACKIE | UCBCNTIE;
}
I get the following data:
Temperature values in ReceviedBuffer, and transmitted value to PuTTY terminal
(i) My first question is that why I'm getting the RecevieBuffer1 values on the terminal and the missing value of the RecevieBuffer[0].
(ii) My second question is that how would I convert the 16-bit raw data to value in Celsius.
Many thanks
To get a 16-bit value from your buffer of bytes you need to cast each byte up to 16-bit values, shift the second byte by 8-bits, and OR the two together. In one line it would look like this:
int16_t value = int16_t(buffer[0]) | int16_t(buffer[1]) << 8;
Based on the value you are reading of 0x0aaf, I would guess the temperature sensor you are using probably outputs the value in in celsius*100 to keep it an integer and still have 100th of degree precision. So to get the value in celsius you'd have to cast to a float or double and divide by 100.0. So 0x0aaf is 2735, meaning 27.35 degrees C.

Arduino I2C Slave to Master communication problem

I am having a problem with reading random data in my Arduino Mega (Master) from my Arduino Uno (Slave) while using I2C communication.
Some background: I am reading Encoder data from the Uno and sending to the Mega via I2C communication. The encoder data is been used in the MEga to adjust the speed of a motor so that the revolutions per second of the different wheels have the same value.
The issue of reading random data arises when I include an IF condition or function.
Even if the IF condition included is an empty one or a call to function which has an empty body it starts to read random wrong data from the Uno.
If i don't have the adjusting part (IF condition/ function) of the code the reading of the data from the Uno works fine.
If anybody can help, it would be greatly appreciated.
Master Code:
#include <SoftwareSerial.h>
#include <SabertoothSimplified.h>
// Include the required Wire library for I2C<br>#include
#include <Wire.h>
// RX on pin 17 (to S2), TX on pin 16 (to S1).
SoftwareSerial SWSerial(NOT_A_PIN, 16);
// Use SWSerial as the serial port.
SabertoothSimplified ST(SWSerial);
//////////////////ENCODER DATA//////////////////
unsigned int revolutions_L_rpm = 0;
unsigned int revolutions_R_rpm = 0;
int16_t x = 0;
int16_t y = 0;
////////////////////////////////////////////////
//////////////VARIABLES FOR ADJUST//////////////
int error = 0;
int kp = 12;
int adjusted = 0;
////////////////////////////////////////////////
////////////////////MOTORS//////////////////////
//Declare the arduino pins
int LEDg = 7;
int LEDr = 6;
int LEDy = 5;
int speedVar = 0;
int speedOne = 0;
int speedTwo = 0;
int power;
////////////////////END/////////////////////////
void setup() {
//initlize the mode of the pins
pinMode(LEDg,OUTPUT);
pinMode(LEDr,OUTPUT);
pinMode(LEDy,OUTPUT);
//set the serial communication rate
Serial.begin(9600);
SWSerial.begin(9600);
Wire.begin();
}
void loop()
{
//check whether arduino is reciving signal or not
if(Serial.available() > 0){
char val = Serial.read();//reads the signal
Serial.print("Recieved: ");
Serial.println(val);
switch(val){
/*********Increase speed by 1 as long as e(triangle) is held*********/
case 'a':
forward();
break;
/*********Decrease speed by 1 as long as g(x) is held*********/
case 'c':
reverse();
break;
/*********Increase speed by 1 as long as e(triangle) is held*********/
case 'd':
turnLeft();
break;
/*********Decrease speed by 1 as long as g(x) is held*********/
case 'b':
turnRight();
break;
/*********Toggle when Circle is held for 5 seconds*********/
case 'f':
toggleSwitch(LEDy);
break;
/*********Toggle when Square is held for 5 seconds*********/
case 'h':
stopMotors();
break;
}
Serial.print("sppedVar = ");
Serial.print(speedVar);
Serial.print("\tleftSpeed: ");
Serial.print(speedOne);
Serial.print("\trightSpeed: ");
Serial.println(speedTwo);
}
Wire.requestFrom(9,4); // Request 4 bytes from slave arduino (9)
byte a = Wire.read();
Serial.print("a: ");
Serial.print(a);
byte b = Wire.read();
Serial.print(" b: ");
Serial.print(b);
byte e = Wire.read();
Serial.print(" --- e: ");
Serial.print(e);
byte f = Wire.read();
Serial.print(" f: ");
Serial.print(f);
x = a;
x = (x << 8) | b;
Serial.print("\tX: ");
Serial.print(x);
y = e;
y = (y << 8) | f;
Serial.print("\tY: ");
Serial.print(y);
revolutions_L_rpm = x;
revolutions_R_rpm = y;
if ((revolutions_L_rpm != revolutions_R_rpm) && (speedVar != 0)){
error = 0;
error = revolutions_L_rpm - revolutions_R_rpm;
adjusted = error/kp;
Serial.print("Error: ");
Serial.print(error);
Serial.print("Error/kp: ");
Serial.println(adjusted);
if ((speedTwo < 20) && (speedTwo > -20)){
speedTwo -= adjusted;
power = speedTwo;
ST.motor(2, -power);
//delay(20);
}
}
// Print out rpm
Serial.print("Left motor rps*100: ");
Serial.print(revolutions_L_rpm);
Serial.print(" ///// Right motor rps*100: ");
Serial.println(revolutions_R_rpm);
// Print out speed
Serial.print("speedOne: ");
Serial.print(speedOne);
Serial.print("\tspeedTwo: ");
Serial.println(speedTwo);
delay(1000);
}
Slave code:
// Include the required Wire library for I2C<br>#include <Wire.h>
#include <Wire.h>
// Checked for main program
volatile boolean counterReady;
// Internal to counting routine
unsigned int timerPeriod;
unsigned int timerTicks;
unsigned long overflowCount;
// The pin the encoder is connected
int encoder_in_L = 2;
int encoder_in_R = 3;
// The number of pulses per revolution
// depends on your index disc!!
unsigned int pulsesperturn = 16;
// The total number of revolutions
int16_t revolutions_L = 0;
int16_t revolutions_R = 0;
int16_t revolutions_L_rpm = 0;
int16_t revolutions_R_rpm = 0;
// Initialize the counter
int16_t pulses_L = 0;
int16_t pulses_R = 0;
byte myData[4];
// This function is called by the interrupt
void count_L() {
pulses_L++;
}
void count_R() {
pulses_R++;
}
void startCounting(unsigned int ms) {
counterReady = false; // time not up yet
timerPeriod = ms; // how many ms to count to
timerTicks = 0; // reset interrupt counter
overflowCount = 0; // no overflows yet
// Reset timer 2
TCCR2A = 0;
TCCR2B = 0;
// Timer 2 - gives us our 1 ms counting interval
// 16 MHz clock (62.5 ns per tick) - prescaled by 128
// counter increments every 8 µs.
// So we count 125 of them, giving exactly 1000 µs (1 ms)
TCCR2A = bit (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
// Timer 2 - interrupt on match (ie. every 1 ms)
TIMSK2 = bit (OCIE2A); // enable Timer2 Interrupt
TCNT2 = 0; // set counter to zero
// Reset prescalers
GTCCR = bit (PSRASY); // reset prescaler now
// start Timer 2
TCCR2B = bit (CS20) | bit (CS22) ; // prescaler of 128
}
ISR (TIMER2_COMPA_vect){
// see if we have reached timing period
if (++timerTicks < timerPeriod)
return;
TCCR2A = 0; // stop timer 2
TCCR2B = 0;
TIMSK2 = 0; // disable Timer2 Interrupt
counterReady = true;
if(counterReady){
Serial.print("Pulses_L: ");
Serial.print(pulses_L);
Serial.print(" Pulses_R: ");
Serial.println(pulses_R);
// multiplying by 100 to get a greater difference to compare
revolutions_L_rpm = (pulses_L * 100) / pulsesperturn;
revolutions_R_rpm = (pulses_R * 100) / pulsesperturn;
// Total revolutions
// revolutions_L = revolutions_L + (pulses_L / pulsesperturn);
// revolutions_R = revolutions_R + (pulses_R / pulsesperturn);
pulses_L = 0;
pulses_R = 0;
}
}
void requestEvent() {
myData[0] = (revolutions_L_rpm >> 8) & 0xFF;
myData[1] = revolutions_L_rpm & 0xFF;
myData[2] = (revolutions_R_rpm >> 8) & 0xFF;
myData[3] = revolutions_R_rpm & 0xFF;
Wire.write(myData, 4); //Sent 4 bytes to master
}
void setup() {
Serial.begin(9600);
pinMode(encoder_in_L, INPUT);
pinMode(encoder_in_R, INPUT);
attachInterrupt(0, count_L, RISING); //attachInterrupt(digitalPinToInterrupt(encoder_in_L, count_L, RISING);
attachInterrupt(1, count_R, RISING); //attachInterrupt(digitalPinToInterrupt(encoder_in_R, count_R, RISING);
// Start the I2C Bus as Slave on address 9
Wire.begin(9);
// Attach a function to trigger when something is received.
Wire.onRequest(requestEvent);
}
void loop() {
// stop Timer 0 interrupts from throwing the count out
byte oldTCCR0A = TCCR0A;
byte oldTCCR0B = TCCR0B;
TCCR0A = 0; // stop timer 0
TCCR0B = 0;
startCounting (1000); // how many ms to count for
while (!counterReady)
{ } // loop until count over
// Print out rpm
Serial.print("Left motor rps: ");
Serial.println(revolutions_L_rpm);
Serial.print("Right motor rps: ");
Serial.println(revolutions_R_rpm);
// Print out revolutions
// Serial.print("Left motor revolution count: ");
// Serial.println(revolutions_L);
// Serial.print("Right motor revolution count: ");
// Serial.println(revolutions_R);
// restart timer 0
TCCR0A = oldTCCR0A;
TCCR0B = oldTCCR0B;
delay(200);
}

msp430G2553 launchpad programming

I am making my program using msp430g2553 launch pad. In this i have taken input from P2.4 and i want my output from P2.0, P2.1 and P2.2.
In this program i have to generate the pulse of 500ms from input. and my output will be three low pulses from the three pins. Meaning whenever i connect my oscilloscope probe to 2.4 i can see the pulse. But the program i made it didn't work. when i connect to the oscilloscope it is showing nothing.
when my input pulse is high i will get the three low pulses output.
here is my code, please check it and tell me what is wrong in the code? since it doesn't contains any error.
code:
#include <msp430g2553.h>
#define CPU_F ((double)16000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
char C_1, C_2;
void System_Clock_Init( void )
{
char i;
_NOP();
WDTCTL = WDTPW + WDTHOLD; // Close Watching dog
delay_ms(50);
if( ( CALBC1_16MHZ == 0xff ) || ( CALDCO_16MHZ == 0xff ) )
((void (*)())RESET_VECTOR)();
BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALDCO_16MHZ; //MCLK=DCOCLK=16MHz
BCSCTL2 = 0x06;//SMCLK=DCOCLK/8=2MHz
BCSCTL3 = 0x00;
IE1 &= ~OFIE;
do
{
IFG1 &= ~OFIFG;
for( i = 0; i < 100; i++ )
{
_NOP();
}
}
while (IFG1 & OFIFG);
_NOP();
}
void IO_INIT(void)
{
NOP();
P2SEL &= ~BIT4;
P2SEL2 &= ~BIT4;
P2REN &= ~BIT4;
/*P2DIR |= BIT2;*/
P2IES |= BIT4;
P2IE |= BIT4;
P2IFG &= ~BIT4;
P2SEL &= ~(BIT0+BIT1);
P2SEL2 &= ~(BIT0+BIT1);
P2REN &= ~(BIT0+BIT1);
//P2DIR &= ~(BIT0+BIT1);
P2OUT &= ~(BIT0+BIT1);
P2SEL &= ~BIT2;
P2SEL2 &= ~BIT2;
P2REN &= ~BIT2;
//P3DIR &= ~BIT1;
P2OUT &= ~BIT2;
}
void main(void)
{
System_Clock_Init();
_NOP();
//WDTCTL = WDT_ARST_1000;
_NOP();
IO_INIT();
_NOP();
_EINT();//open all interrupt
_NOP();
LPM3;
_NOP();
while(1);
}
#pragma vector = PORT2_VECTOR
__interrupt void PORT_C_Interrupt(void)
{
_NOP();
delay_us(20);
if( C_1 == 0xff)
{
if(!( P2IN & BIT4 )) C_2 = 0xff;
}
else
{
if(!( P2IN & BIT4 )) C_1 = 0xff;
}
if(( C_1 == 0xff) && ( C_2 == 0xff))
{
//output A B D
P2OUT |= BIT0;
delay_ms(2);
P2OUT |= BIT1;
P2OUT &= ~BIT0;
delay_ms(2);
P2OUT |= BIT2;
P2OUT &= ~BIT1;
delay_ms(2);
P2OUT &= ~BIT2;
delay_ms(2);
P2OUT ^= BIT1;
P2IFG &= ~BIT1;
C_1 =0x00;
C_2 =0x00;
}
_NOP();
}
P2IFG &= ~BIT1;
The interrupt came from P2.4. This line does not clear the interrupt for pin 4, so the interrupt handler will be called continuously.
/*P2DIR |= BIT2;*/
//P2DIR &= ~(BIT0+BIT1);
If you actually want those pins to te outputs, it would be a good idea not to comment out their configuration.

Convert an arduino library for touchscreen to a general c library

I have been using the adafruit 3.5'' tft touchscreen break out board with arduino. It has arduino library available for this purpose. I have attached the library below. I am trying to make this touchscreen work without the arduino board with atmega16 . I have changed the library into a c file accordingly. I have written a program to just change the screen color, but that also in not happening. I do not understand where is the problem. can some one help me out. pls !!!
This the code after editing in c file .
#define SS PINB4
#define MOSI PINB5
#define MISO PINB6
#define SCK PINB7
#define CS PIND0
#define DC PIND1
#define RST PIND6
void delay(uint8_t a)
{
unsigned int i,j;
for(i=0;i<a;i++)
{
for(j=0;j<1024;j++);
}
}
void Adafruit_HX8357() {
_cs = CS;
_dc = DC;
_rst = RST;
_mosi = MOSI;
_sck = SCK;
}
void Adafruit_GFX(int16_t w, int16_t h)
{
_width = w;
_height = h;
rotation = 0;
cursor_y = cursor_x = 0;
textsize = 1;
textcolor = textbgcolor = 0x001F;
}
void setRotation(uint8_t m) {
writecommand(HX8357_MADCTL);
rotation = m % 4; // can't be higher than 3
switch (rotation) {
case 0:
writedata(MADCTL_MX | MADCTL_MY | MADCTL_RGB);
_width = HX8357_TFTWIDTH;
_height = HX8357_TFTHEIGHT;
break;
case 1:
writedata(MADCTL_MV | MADCTL_MY | MADCTL_RGB);
_width = HX8357_TFTHEIGHT;
_height = HX8357_TFTWIDTH;
break;
case 2:
writedata( MADCTL_RGB);
_width = HX8357_TFTWIDTH;
_height = HX8357_TFTHEIGHT;
break;
case 3:
writedata(MADCTL_MX | MADCTL_MV | MADCTL_RGB);
_width = HX8357_TFTHEIGHT;
_height = HX8357_TFTWIDTH;
break;
}
}
void writecommand(uint8_t c) {
PORTD &= ~(1<<PIND1);//
//dcport &= ~dcpinmask;
//digitalWrite(_dc, LOW);
PORTB &= ~(1<<PINB7);//clkport &= ~clkpinmask;
//digitalWrite(_sclk, LOW);
PORTD &= ~(1<<PIND0);//*csport &= ~cspinmask;
//digitalWrite(_cs, LOW);
spiwrite(c);
//Serial.print("Command 0x"); Serial.println(c, HEX);
PORTD |= (1<<PIND0);//*csport |= cspinmask;
//digitalWrite(_cs, HIGH);
}
void writedata(uint8_t c) {
PORTD |= (1<<PIND1);//
//dcport |= dcpinmask;
//digitalWrite(_dc, HIGH);
PORTB &= ~(1<<PINB7);//clkport &= ~clkpinmask;
//digitalWrite(_sclk, LOW);
PORTD &= ~(1<<PIND0);// *csport &= ~cspinmask;
//digitalWrite(_cs, LOW);
spiwrite(c);
//Serial.print("Data 0x"); Serial.println(c, HEX);
//digitalWrite(_cs, HIGH);
PORTD |= (1<<PIND0);//*csport |= cspinmask;
}
void spiwrite(uint8_t c) {
SPDR = c;
while(!(SPSR & (1<<SPIF) ));
}
void init()
{
DDRB = (1<<PINB5)|(1<<PINB7);
SPCR = 0x50;
SPSR = 0x00;
}
void begins(uint8_t type) {
if (_rst > 0) {
DDRD |= (1<<PIND6);//pinMode(_rst, OUTPUT);
_rst = 0;// reset LOW
}
DDRD |= (1<< PIND1);//pinMode(_dc, OUTPUT);
DDRD |= (1<< PIND0);//pinMode(_cs, OUTPUT);
// toggle RST low to reset
if (_rst > 0) {
_rst = 1;//digitalWrite(_rst, HIGH);
delay(100);
_rst = 0;//digitalWrite(_rst, LOW);
delay(100);
_rst = 1;//digitalWrite(_rst, HIGH);
delay(150);
}
writecommand(HX8357_SWRESET);
// setextc
writecommand(HX8357D_SETC);
writedata(0xFF);
writedata(0x83);
writedata(0x57);
delay(300);
// setRGB which also enables SDO
writecommand(HX8357_SETRGB);
writedata(0x80); //enable SDO pin!
// writedata(0x00); //disable SDO pin!
writedata(0x0);
writedata(0x06);
writedata(0x06);
writecommand(HX8357D_SETCOM);
writedata(0x25); // -1.52V
writecommand(HX8357_SETOSC);
writedata(0x68); // Normal mode 70Hz, Idle mode 55 Hz
writecommand(HX8357_SETPANEL); //Set Panel
writedata(0x05); // BGR, Gate direction swapped
writecommand(HX8357_SETPWR1);
writedata(0x00); // Not deep standby
writedata(0x15); //BT
writedata(0x1C); //VSPR
writedata(0x1C); //VSNR
writedata(0x83); //AP
writedata(0xAA); //FS
writecommand(HX8357D_SETSTBA);
writedata(0x50); //OPON normal
writedata(0x50); //OPON idle
writedata(0x01); //STBA
writedata(0x3C); //STBA
writedata(0x1E); //STBA
writedata(0x08); //GEN
writecommand(HX8357D_SETCYC);
writedata(0x02); //NW 0x02
writedata(0x40); //RTN
writedata(0x00); //DIV
writedata(0x2A); //DUM
writedata(0x2A); //DUM
writedata(0x0D); //GDON
writedata(0x78); //GDOFF
writecommand(HX8357D_SETGAMMA);
writedata(0x02);
writedata(0x0A);
writedata(0x11);
writedata(0x1d);
writedata(0x23);
writedata(0x35);
writedata(0x41);
writedata(0x4b);
writedata(0x4b);
writedata(0x42);
writedata(0x3A);
writedata(0x27);
writedata(0x1B);
writedata(0x08);
writedata(0x09);
writedata(0x03);
writedata(0x02);
writedata(0x0A);
writedata(0x11);
writedata(0x1d);
writedata(0x23);
writedata(0x35);
writedata(0x41);
writedata(0x4b);
writedata(0x4b);
writedata(0x42);
writedata(0x3A);
writedata(0x27);
writedata(0x1B);
writedata(0x08);
writedata(0x09);
writedata(0x03);
writedata(0x00);
writedata(0x01);
writecommand(HX8357_COLMOD);
writedata(0x55); // 16 bit
writecommand(HX8357_MADCTL);
writedata(0xC0);
writecommand(HX8357_TEON); // TE off
writedata(0x00);
writecommand(HX8357_TEARLINE); // tear line
writedata(0x00);
writedata(0x02);
writecommand(HX8357_SLPOUT); //Exit Sleep
delay(150);
writecommand(HX8357_DISPON); // display on
delay(50);
}
void drawPixel(int16_t x, int16_t y, uint16_t color) {
if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
setAddrWindow(x,y,x+1,y+1);
//digitalWrite(_dc, HIGH);
PORTD |= (1<<PIND1);// dcport |= dcpinmask;
//digitalWrite(_cs, LOW);
PORTD &= ~(1<<PIND0);//csport &= ~cspinmask;
spiwrite(color >> 8);
spiwrite(color);
PORTD |= (1<<PIND0);//*csport |= cspinmask;
//digitalWrite(_cs, HIGH);
}
void drawFastVLine(int16_t x, int16_t y, int16_t h,uint16_t color) {
// Rudimentary clipping
if((x >= _width) || (y >= _height)) return;
if((y+h-1) >= _height)
h = _height-y;
setAddrWindow(x, y, x, y+h-1);
uint8_t hi = color >> 8, lo = color;
PORTD |= (1<<PIND1);//*dcport |= dcpinmask;
//digitalWrite(_dc, HIGH);
PORTD &= ~(1<<PIND0);//*csport &= ~cspinmask;
//digitalWrite(_cs, LOW);
while (h--) {
spiwrite(hi);
spiwrite(lo);
}
PORTD |= (1<<PIND0);//*csport |= cspinmask;
//digitalWrite(_cs, HIGH);
}
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color){
drawFastHLine(x, y, w, color);
drawFastHLine(x, y+h-1, w, color);
drawFastVLine(x, y, h, color);
drawFastVLine(x+w-1, y, h, color);
}
void drawFastHLine(int16_t x, int16_t y, int16_t w,uint16_t color) {
// Rudimentary clipping
if((x >= _width) || (y >= _height)) return;
if((x+w-1) >= _width) w = _width-x;
setAddrWindow(x, y, x+w-1, y);
uint8_t hi = color >> 8, lo = color;
PORTD |= (1<<PIND1);//*dcport |= dcpinmask;
PORTD &= ~(1<<PIND0);//*csport &= ~cspinmask;
//digitalWrite(_dc, HIGH);
//digitalWrite(_cs, LOW);
while (w--) {
spiwrite(hi);
spiwrite(lo);
}
PORTD |= (1<<PIND0);//*csport |= cspinmask;
//digitalWrite(_cs, HIGH);
}
void fillScreen(uint16_t color) {
drawRect(0, 0, _width, _height, color);
}
void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1,uint16_t y1)
{
writecommand(HX8357_CASET); // Column addr set
writedata(x0 >> 8);
writedata(x0 & 0xFF); // XSTART
writedata(x1 >> 8);
writedata(x1 & 0xFF); // XEND
writecommand(HX8357_PASET); // Row addr set
writedata(y0>>8);
writedata(y0); // YSTART
writedata(y1>>8);
writedata(y1); // YEND
writecommand(HX8357_RAMWR); // write to RAM
}
void setCursor(int16_t x, int16_t y) {
cursor_x = x;
cursor_y = y;
}
void setTextSize(uint8_t s) {
textsize = (s > 0) ? s : 1;
}
void setTextColor(uint16_t c) {
textcolor = textbgcolor = c;
}
int main(void)
{
init();
Adafruit_HX8357();
begins(HX8357D);
Adafruit_GFX(HX8357_TFTWIDTH, HX8357_TFTHEIGHT);
setRotation(3);
fillScreen(HX8357_RED);
return 0;
}
The link for original library is
https://github.com/adafruit/Adafruit_HX8357_Library
https://github.com/adafruit/Adafruit-GFX-Library

Why does serial communication only work in one direction (chip->PC) with my code?

I am writing code for an Arduino Mega 2560 in C and I am trying to do bidirectional communication over the serial port. However, only sending data from the Arduino to the PC works - the other way doesn't. The RX LED on the arduino shortly lights up, but my code doesn't receive the data (the LED connected to "pin 13" doesn't light up). Does anyone know how to fix this?
Here's the code that's running on the arduino:
#define USART_BAUDRATE 500000
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
static void serial_init(void) {
// load upper 8 bits of the baud rate into the high byte of the UBRR register
UBRR0H = (BAUD_PRESCALE >> 8);
// load lower 8 bits of the baud rate into the low byte of the UBRR register
UBRR0L = BAUD_PRESCALE;
// 8data,1stopbit
UCSR0C = (0 << UMSEL00) | (1 << UCSZ00) | (1 << UCSZ01);
// turn on the transmission and reception circuitry
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (0 << UCSZ02);
}
static void sendbyte(uint8_t b) {
// do nothing until UDR is ready for more data to be written to it
while ((UCSR0A & (1 << UDRE0)) == 0) {};
// memory was cleared - write to it
UDR0 = b;
}
static void digi_init() {
// configure port B7 (arduino digital port 13) as output and set it low
PORTB = (0<<PB7);
DDRB = (1<<DDB7);
}
static void digi_set(int val) {
PORTB = (val<<PB7);
}
int main(void) {
serial_init();
digi_init();
while (1) {
if ((UCSR0A & (1 << RXC0)) == 1) {
// we got some data, light up the LED!
digi_set(1);
}
_delay_ms(50);
sendbyte('.');
}
}
And here's the code that's running on the PC:
int main(int argc, char *argv[]) {
char *serialdevicepath = "/dev/ttyACM0";
fprintf(stderr, "Connecting to serial device ...\n");
int serial_fd = open(serialdevicepath, O_RDWR | O_NOCTTY);
struct termios config;
if(tcgetattr(serial_fd, &config) < 0) exit(1);
config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON);
config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
config.c_cflag &= ~(CSIZE | PARENB);
config.c_cflag |= CS8;
config.c_cc[VMIN] = 1;
config.c_cc[VTIME] = 0;
if(cfsetispeed(&config, B500000) < 0 || cfsetospeed(&config, B500000) < 0) exit(1);
if(tcsetattr(serial_fd, TCSAFLUSH, &config) < 0) exit(1);
FILE *serial = fdopen(serial_fd, "r");
setbuf(stdin, NULL);
fcntl(0/*stdin*/, F_SETFL, O_NONBLOCK);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
setbuf(serial, NULL);
while (1) {
char c;
while (read(0, &c, 1) == 1) {
if (c != '+' && c != '-') continue;
uint8_t val = (c == '+') ? 42 : 41;
if (write(serial_fd, &val, 1) != 1) {
assert(0);
}
}
char b = fgetc(serial))&0xe0);
fprintf(stderr, "read 0x%x\n", b);
}
return 0;
}
(And yes, I am typing <+> on the PC so that it does send data. Also, I tried turning on the LED from the code directly and it worked.)
if ((UCSR0A & (1 << RXC0)) == 1)
That test is wrong, it will never be 1. The & operator here will produce either 0 or (1 << RXC0). Favor it this way instead:
if ((UCSR0A & (1 << RXC0)) != 0)
Or in C you'd typically write it this way since any non-zero value is logically true:
if (UCSR0A & (1 << RXC0))

Resources