I am transferring my microcontroller settings through a serial connection from my pc. I try to turn on and off two leds based on a command sent from the PC. Please take a look at the code:
void initUc(){
ledsCount = USART_Receive() - '0';
USART_Transmit('1');
debugBlink();
if(ledsCount > 0){
//leds = (Pin *) malloc(ledsCount*sizeof(Pin));;
leds = new Pin[ledsCount];
for(uint8_t i = 0; i<ledsCount; i++){
uint8_t command = USART_Receive()-'0';
char rport = USART_Receive();
uint8_t rpin = USART_Receive()-'0';
bool on = USART_Receive()-'0';
leds[i] = new Pin(rport,rpin,true,on);
USART_Transmit('1');
debugBlink();
}
}
}
This function is used to initialize (instantiate) the two leds. The leds are instances of Pin class.
How it works:
- I send the number of leds on my board;
- I send a through serial a string like "4A01" where 4 is the command code (has no importance right here), A is the port, 0 is the pin and 1 is pin's initial state;
- I instantiate the ping a send a response.
Code:
switch(command)
{
case COMMAND_CODE_BLINKING_LED:
char rport = USART_Receive();
uint8_t rpin = USART_Receive()-'0';
bool on = USART_Receive()-'0';
uint8_t i;
for(i = 0; i<ledsCount; i++){
// if(leds[i].checkPinLocation(rport,rpin)){
//leds[i].run(on);
if(on) leds[i].setToHigh();
else leds[i].setToLow();
//USART_Transmit((PINA & (1<<PA0)?1:0)+'0');
//break;
debugBlink();
//}
}
USART_Transmit(on+'0');
break;
}
After the initialization I am sending a string from my computer to my microcontroller like I explained earlier and the flow it's almost the same, the only difference is that here I am trying to turn on or off the correspondent led.
The problem is that if I set my two pins in the initialization phase like 4A01 and 4A11 (which means both pins are initially High) and I try the upper code on both of them with the commands 4A00 and 4A10 (which should turn them off), only the first one turns off and the other one still remains high.
I don't know why is this happening, the code seems ok.
I'll post the code for the Pin class
class Pin
{
private:
uint8_t pin;
volatile uint8_t* Port;
volatile uint8_t* ddr_port;
volatile uint8_t* pin_val_port;
public:
Pin(){};
Pin(char port, uint8_t pin, bool isOutput = false, bool isOn = false)
{
this->Port = findPort(port);
this->ddr_port = this->Port - 1;
this->pin_val_port = this->ddr_port - 1;
this->pin = pin;
setIsOutput(isOutput);
if(isOn) setToHigh();
else setToLow();
}
volatile uint8_t* findPort(char port){
volatile uint8_t* p;
switch(port)
{
case 'A':
p = &PORTA;
break;
case 'B':
p = &PORTB;
break;
case 'C':
p = &PORTC;
break;
case 'D':
p = &PORTD;
break;
}
return p;
}
void setIsOutput(bool isOutput){
if(isOutput)
*this->ddr_port |= 1<<pin;
else
*this->ddr_port &= 0<<pin;
}
void setToHigh(){
*this->Port |= 1 << pin;
}
void setToLow(){
*this->Port &= ~(1 << pin);
}
void run(bool on){
if(on)
this->setToHigh();
else
this->setToLow();
}
bool checkPinLocation(char port, int pin){
return (this->Port == findPort(port) && this->pin == pin);
}
Pin* operator=(Pin *obj){
return obj;
}
};
I am transferring my microcontroller settings through a serial connection from my pc. I try to turn on and off two leds based on a command sent from the PC. Please take a look at the code:
void initUc(){
ledsCount = USART_Receive() - '0';
USART_Transmit('1');
debugBlink();
if(ledsCount > 0){
//leds = (Pin *) malloc(ledsCount*sizeof(Pin));;
leds = new Pin[ledsCount];
for(uint8_t i = 0; i<ledsCount; i++){
uint8_t command = USART_Receive()-'0';
char rport = USART_Receive();
uint8_t rpin = USART_Receive()-'0';
bool on = USART_Receive()-'0';
leds[i] = new Pin(rport,rpin,true,on);
USART_Transmit('1');
debugBlink();
}
}
}
This function is used to initialize (instantiate) the two leds. The leds are instances of Pin class.
How it works:
- I send the number of leds on my board;
- I send a through serial a string like "4A01" where 4 is the command code (has no importance right here), A is the port, 0 is the pin and 1 is pin's initial state;
- I instantiate the ping a send a response.
Code:
switch(command)
{
case COMMAND_CODE_BLINKING_LED:
char rport = USART_Receive();
uint8_t rpin = USART_Receive()-'0';
bool on = USART_Receive()-'0';
uint8_t i;
for(i = 0; i<ledsCount; i++){
// if(leds[i].checkPinLocation(rport,rpin)){
//leds[i].run(on);
if(on) leds[i].setToHigh();
else leds[i].setToLow();
//USART_Transmit((PINA & (1<<PA0)?1:0)+'0');
//break;
debugBlink();
//}
}
USART_Transmit(on+'0');
break;
}
After the initialization I am sending a string from my computer to my microcontroller like I explained earlier and the flow it's almost the same, the only difference is that here I am trying to turn on or off the correspondent led.
The problem is that if I set my two pins in the initialization phase like 4A01 and 4A11 (which means both pins are initially High) and I try the upper code on both of them with the commands 4A00 and 4A10 (which should turn them off), only the first one turns off and the other one still remains high.
I don't know why is this happening, the code seems ok.
I'll post the code for the Pin class
class Pin
{
private:
uint8_t pin;
volatile uint8_t* Port;
volatile uint8_t* ddr_port;
volatile uint8_t* pin_val_port;
public:
Pin(){};
Pin(char port, uint8_t pin, bool isOutput = false, bool isOn = false)
{
this->Port = findPort(port);
this->ddr_port = this->Port - 1;
this->pin_val_port = this->ddr_port - 1;
this->pin = pin;
setIsOutput(isOutput);
if(isOn) setToHigh();
else setToLow();
}
volatile uint8_t* findPort(char port){
volatile uint8_t* p;
switch(port)
{
case 'A':
p = &PORTA;
break;
case 'B':
p = &PORTB;
break;
case 'C':
p = &PORTC;
break;
case 'D':
p = &PORTD;
break;
}
return p;
}
void setIsOutput(bool isOutput){
if(isOutput)
*this->ddr_port |= 1<<pin;
else
*this->ddr_port &= 0<<pin;
}
void setToHigh(){
*this->Port |= 1 << pin;
}
void setToLow(){
*this->Port &= ~(1 << pin);
}
void run(bool on){
if(on)
this->setToHigh();
else
this->setToLow();
}
bool checkPinLocation(char port, int pin){
return (this->Port == findPort(port) && this->pin == pin);
}
Pin* operator=(Pin *obj){
return obj;
}
};
0 commentaires:
Enregistrer un commentaire