Why doesn't my program recognize the PORTbits.RCx == 0 condition? - c

void UART_init(void){
ANSELB = 0; //set PORT B to digital port
TRISBbits.TRISB5 = 1; //set RX pin to input
TRISBbits.TRISB7 = 0; //set TX pin as output
SPBRGH = 0;
SPBRGL = 25; //set baud rate to 9600
BRGH = 0;
BRG16 = 0;
SYNC = 0;
SPEN = 1; //enable serial port pins
TX9 = 0; //set 9 bit tranmission
RX9 = 0; //set 9 bit receive
TXEN = 1; //enable transmission
CREN = 1; //enable receiver
}
void UART_write(char data){
while(TRMT == 0);
TXREG = data;
}
void UART_write_string(char *text){
for(int i=0; text[i] != '\0'; i++){
UART_write(text[i]);
}
}
char UART_read(){
while(RCIF == 0);
return RCREG;
}
char URAT_read_string(char *stringprimit, int lungime){
for(int i=0; i < lungime; i++){
stringprimit[i] = UART_read();
}
}
int main(int argc, char** argv) {
OSCCONbits.IRCF = 0b1111; //set operating frequency to 31kHz (0b1111) for 16MHz
//WDTCONbits.WDTPS = 0b01110;
//CLRWDT();
//0b01100; //set WTD interval at 4s
UART_init();
//Activam pull-up
OPTION_REGbits.nWPUEN = 0;
WPUCbits.WPUC2 = 1;
WPUCbits.WPUC6 = 1;
WPUCbits.WPUC7 = 1;
WPUCbits.WPUC0 = 0;
WPUCbits.WPUC1 = 0;
WPUCbits.WPUC3 = 1;
//Led-uri
TRISAbits.TRISA1 = 0; // set as output
TRISAbits.TRISA2 = 0; // set as output
ANSELAbits.ANSA1 = 0; //pin digital
ANSELAbits.ANSA2 = 0; //pin digital
ANSELAbits.ANSA0 = 1; //set to analogic pin
TRISAbits.TRISA0 = 1; //set as input
ANSELCbits.ANSC0 = 0; //set to digital pin
ANSELCbits.ANSC1 = 0; //set to digital pin
TRISCbits.TRISC0 = 0; //set as output
TRISCbits.TRISC1 = 0; //set as output
ANSELCbits.ANSC2 = 0; //set to digital pin
ANSELCbits.ANSC6 = 0; //set to digital pin
ANSELCbits.ANSC7 = 0; //set to digital pin
TRISCbits.TRISC2 = 1; //set as input
TRISCbits.TRISC6 = 1; //set as input
TRISCbits.TRISC7 = 1; //set as input
PORTCbits.RC0 = 1;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 1;
char user_input;
UART_write_string("1. rotate right ");
UART_write('\r');
UART_write_string("2. rotate left");
UART_write('\r');
UART_write_string("3. stop");
UART_write('\r');
UART_write_string("4. Deactivate UART");
UART_write('\r');
UART_write_string("select:");
while(1){
//CLRWDT();
user_input = UART_read();
if(PORTCbits.RC7 == 0 ){ //motor rotates right
user_input = '1';
PORTCbits.RC0 = 1;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 1;
}
if(PORTCbits.RC6 == 0 ){ //motor rotates left
user_input = '2';
PORTCbits.RC0 = 0;
PORTCbits.RC1 = 1;
PORTAbits.RA1 = 1;
PORTAbits.RA2 = 0;
}
if(PORTCbits.RC2 == 0 ){ //motor stop
user_input = '3';
PORTCbits.RC0 = 0;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 0;
}
if(user_input =='1') {//motor rotates right
PORTCbits.RC0 = 1;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 1;
}
if( user_input =='2'){ //motor rotates left
PORTCbits.RC0 = 0;
PORTCbits.RC1 = 1;
PORTAbits.RA1 = 1;
PORTAbits.RA2 = 0;
}
if(user_input =='3'){ //motor stop
PORTCbits.RC0 = 0;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 0;
}
if(user_input =='4'){ //deactivate UART
CREN = 0;
}
}
return (EXIT_SUCCESS);
}
In this project I tried to control a DC motor with two methods, the first method is UART with user's input and the second with buttons.
The scope: When I press the numer 1 from the keyboard I want the motor rotates to the right, 2- left, 3 - stop. This works properly, but the problem is with the buttons, when I press the RC7 button nothing happens.
RC7 - means the motor rotates right, RC6 - them motor rotates left, RC2 - the motor stop
From what I can tell, my program doesn't even see those conditions, like PORTbits.RC7 == 0.

From the code, I can see that the function:
char UART_read(){
while(RCIF == 0);
return RCREG;
}
is blocking on while(RCIF == 0);
and I think this is the reason your Buttons are not working because at the very beginning of the while(1) you have called UART_read();.
And you mentioned it yourself that the output is as expected for UART data, so this answers your question.
To make it work, you have to write a UART Rx Interrupt so that your program should not be blocking/waiting on UART to Receive data.
Edit:
As per your comment, that you are disabling the UART reception using CREN, then you should also check if the Receiver is enabled prior to reading the Rx Data register, you can modify the UART receive function as below:
char UART_read(){
if(CREN == 0) {
return '\0'; //Return NULL Character
}
while(RCIF == 0);
return RCREG;
}

Related

Motor runs despite not calling it

currently doing a project with a board with several routines:
#include <xc.h>
#include "config.h"
#define TRUE 1
#define FALSE 0
#define SW1 PORTBbits.RB4
#define SW2 PORTBbits.RB5
#define PB3 PORTCbits.RC3 //for testing
#define PB2 PORTDbits.RD1
#define PB7 PORTCbits.RC7
#define PB8 PORTCbits.RC6
#define MOTOR PORTDbits.RD0
void initSysPins(void);
void ReadLight(void);
void ReadTemperature(void);
void ReadSoilMoisture(void);
void MessageDoze(void);
void MessageSleep(void);
void lcdClear(void);
void initLCD(void);
void initSysInt(void);
void initSysTimer(void);
void pwrMgmt(void);
void initPWM(void);
unsigned char detPB3(void); //for testing
unsigned char detPB2(void);
unsigned char detPB7(void);
unsigned char detPB8(void);
void main(void) {
initSysInt();
initSysPins();
initSysTimer();
CPUDOZE = 0;
while(TRUE){
if(SW1 == 1 && SW2 == 0){
ReadTemperature();
}
else if (SW1 == 0 && SW2 == 1){
ReadLight();
}
else if (SW1 == 1 && SW2 == 1){
ReadSoilMoisture();
}
else {
lcdClear();
}
pwrMgmt();
//pwrMgmt1();
}
}
void pwrMgmt(void){
if(PB2 == 0){
lcdClear();
ROI = 1;
MessageSleep();
SLEEP();
__delay_ms(500);
}
else if(PB7 == 0){
lcdClear();
MessageDoze();
DOZEN= 1;
ROI = 1;
}
}
unsigned char detPB3(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB3 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB3 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB3 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB2(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB2 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB2 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB2 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB7(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB7 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB7 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB7 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB8(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB8 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB8 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB8 == 0);//wait for sw1 to be released
}
}
return detect;
}
The only problem is that my DC motor still runs on its own despite only being called inside my soil moisture function. the other functions just use LCD and LED and work fine. I've tried working around this by putting MOTOR = 0; inside my main but that doesn't do anything.
EDIT: Works on its own before integration with the rest of my codes.
ReadSoilMoisture():
#include <xc.h>
#include "config.h"
#define lcd_Clear 0b00000001
#define LCD_DATA PORTD
#define LCD_RS PORTEbits.RE1 //RS signal for LCD
#define LCD_E PORTEbits.RE0 // E signal for LCD
#define MOTOR PORTDbits.RD0
void initSysPins(void);
void lcdWriteData(char);
void lcdWriteCtrl(char);
void lcdWriteMessage(char message[], unsigned char row);
void lcdSetPos(unsigned char row, unsigned char col);
void initPWM(void);
//void Message(void);
void Message1(void);
void Message2(void);
void Message(void);
void initLCD(void);
void initADC(void);
unsigned int readPot1(void);
void ReadSoilMoisture(void) {
unsigned int raw;
unsigned char pwmCycle = 0;
// float fresult;
// char res[20];
initLCD();
initSysPins();
initPWM();
initADC();
PWM6CONbits.EN = 1;
// raw = readPot1();
int i = 0;
for(i = 0; i<=40; i++) {
raw = readPot1();
if (raw == 0 && raw <= 10)
{
PORTA = 0x00;
}
else if (raw == 11 && raw <=100)
{
PORTA = 0b00001001; //RED
MOTOR = 1;
pwmCycle = 4000;
__delay_ms(5000);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
else if (raw == 101 && raw <= 1000)
{
PORTA = 0b00010010; //YELLOW
MOTOR = 1;
pwmCycle = 1500;
__delay_ms(3000);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message1();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
else if (raw == 1001 && raw <= 1023)
{
PORTA = 0b00100100; //GREEN
MOTOR = 1;
pwmCycle = 900;
__delay_ms(800);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message2();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
}
}
void Message(void){
char message[] = "Soil Moisture";
char message1[] = "Is 55%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void Message1(void){
char message[] = "Soil Moisture";
char message1[] = "Is 75%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void Message2(void){
char message[] = "Soil Moisture";
char message1[] = "Is 95%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void initPWM(void)
{
CCPTMRS1 = PORTDbits.RD0;
PWM6CON = 0b00000000;
T2PR = 249;
PWM6DCH = 0b01111101;
PWM6DCL = 0b00000000;
T2CON = 0b11110000;
T2CLKCON = 0b00000001;
RA2PPS = 0x0E;
}
Any guess as to what I can do?

Could there be a way to escape this loop?(problem with fade and leds)

int led1 = 3;
int led2 = 5;
int led3 = 6;
int led4 = 9;
int m = 1;
int brightness = 10;
int fadeAmount = 5;
int led;
int one = 1;
void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
}
void loop()
{
if (m == 4 or m == 1) {
one = -one;
}
if (intensite <= 5){
m = m + one;
}
if (m == 1) {
led = led1;
}
if (m == 2) {
led = led2;
}
if (m == 3) {
led = led3;
}
if (m == 4) {
led = led4;
}
brightness = brightness + fadeAmount;
if (brightness <= 5 or brightness >= 255) {
fadeAmount = -fadeAmount;
}
analogWrite(led,brightness);
delay(10);
}
When I run this part of the code, it just gets stuck in a infinite loop at the top led and it does not go back down the way it should which I fail to see. It would be of great help if one could help me understand my mistake. The aim is to make a code that lights leds from right to left (led1 to led4) then left to right (led4 to led1), not simply turning them on but fading them.
I tried my best to stay as close to your code as possible. So your code didn't work because it don't make much sense. Why would you make this one variable? It just complicated all the things. Just put a boolean which indicates whether you are going left or not and change it based on the current value of m. Here is how:
int led1 = 3;
int led2 = 5;
int led3 = 6;
int led4 = 9;
int m = 1;
int brightness = 10;
int fadeAmount = 5;
int led;
bool goingLeft;
void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
}
void loop()
{
if (m == 1) { // If we are on the right side we set goingLeft to true
goingLeft = true;
}else if(m == 4){ // If we are on the left side we set goingLeft to false
goingLeft = false;
}
if (brightness <= 5 && goingLeft){ // if we are moving left then we increment the m variable
m++;
}else if(brightness <= 5){ // if we are moving right we decrement it
m--;
}
if (m == 1) {
led = led1;
}
if (m == 2) {
led = led2;
}
if (m == 3) {
led = led3;
}
if (m == 4) {
led = led4;
}
brightness = brightness + fadeAmount;
if (brightness <= 5 or brightness >= 255) {
fadeAmount = -fadeAmount;
}
analogWrite(led,brightness);
delay(10);
}
If I were you I would do this in a completly diffrent way by using for loops but as I said earlier I tried to stay as close to your code as I could.
Also I saw that you used or in your code. Don't do it!!! In C languages the or operator is || not or

Problems writing to 2-Dimensional arrays, Embedded C

I am having trouble understanding what is going on with my code, mainly regarding 2D arrays. I am trying to use a function in my communication file to decode a command string from a terminal. I want it to break the string down and output the answers by updating the global buffers. I am having trouble writing to these arrays and I do not understand why. In the code below I just assigned a value to the USART1_Command char array where in the actual program it comes from a terminal.
Main and declarations:
//Global declarations//
#define USART1_BUFFER_SIZE (100)
#define MAX_COMMAND_INT_VALUES (50)
#define MAX_COMMAND_STR_VALUES (50)
#define MAX_COMMAND_STR_LENGTH (50)
char USART1_Buffer[USART1_BUFFER_SIZE];
uint16_t USART1_Write_Index = 0;
char USART1_Command[MAX_COMMAND_STR_LENGTH] = {0x00};
uint16_t USART1_Command_Int_Values[MAX_COMMAND_INT_VALUES] = {0x00};
char **USART1_Command_Str_Values;
void main(void){
USART1_Command_Str_Values = (char **)calloc(MAX_COMMAND_STR_VALUES, sizeof(char *));
uint16_t i = 0;
for(i = 0; i < MAX_COMMAND_INT_VALUES; i++){
USART1_Command_Str_Values[i] = (char *)calloc(MAX_COMMAND_STR_LENGTH, sizeof(char));
}
strcpy(USART1_Command, "TESTCOMMAND,45,36,21-TEST1-TEST2");
USART1_Command_Decode(USART1_Command, USART1_Command_Int_Values, USART1_Command_Str_Values, MAX_COMMAND_INT_VALUES, MAX_COMMAND_STR_VALUES, MAX_COMMAND_STR_LENGTH);
while(1){
}
}
and the function:
void USART1_Command_Decode(char *command, uint16_t *int_values_buffer, char **str_values_buffer, uint16_t int_values_buffer_size, uint16_t str_values_buffer_size, uint16_t str_values_size){
uint16_t i = 0;
uint16_t j = 0;
uint16_t length = strlen(command);
int16_t Int_Values_Index = -1;
bool Int_Value_Flag = false;
char **Int_Values;
Int_Values = (char**)calloc(int_values_buffer_size, sizeof(char*));
for(i = 0; i < int_values_buffer_size; i++){
Int_Values[i] = (char*)calloc(str_values_size, sizeof(char));
}
const uint16_t Max_Str_Values = 50;
int16_t Str_Values_Index = -1;
bool Str_Value_Flag = false;
for(i = 0; i < length; i++){
switch(command[i]){
case ',': //Signifies integer value//
if(Int_Values_Index < int_values_buffer_size){
Int_Values_Index++;
Int_Value_Flag = true;
Str_Value_Flag = false;
j = 0;
}
command[i] = 0x00;
break;
case '-': //Signifies string value//
if(Str_Values_Index < str_values_buffer_size){
Str_Values_Index++;
Str_Value_Flag = true;
Int_Value_Flag = false;
j = 0;
}
command[i] = 0x00;
break;
default:
if(Int_Value_Flag){
Int_Values[Int_Values_Index][j] = command[i];
command[i] = 0x00;
j++;
}
if(Str_Value_Flag){
str_values_buffer[Str_Values_Index][j] = command[i];
command[i] = 0x00;
j++;
}
break;
}
}
//Convert integer strings to integers//
for(i = 1; i <= Int_Values_Index; i++){
int_values_buffer[i] = atoi(Int_Values[i]);
}
for(i = 0; i < int_values_buffer_size; i++){
free(Int_Values[i]);
}
free(Int_Values);
}
I figured this out, the way that I was able to make it work was as follows:
Declaration of Global variables:
#define MAX_COMMAND_INT_VALUES (50)
#define MAX_COMMAND_STR_VALUES (50)
#define MAX_COMMAND_STR_LENGTH (50)
char USART1_Command[MAX_COMMAND_STR_LENGTH] = {0x00};
uint16_t USART1_Command_Int_Values[MAX_COMMAND_INT_VALUES] = {0x00};
char USART1_Command_Str_Values[MAX_COMMAND_STR_VALUES][MAX_COMMAND_STR_LENGTH];
Function:
void USART1_Command_Decode(char *command, uint16_t *int_values_buffer, uint16_t int_values_buffer_size, uint16_t str_values_buffer_size, uint16_t str_values_size, char str_values_buffer[str_values_buffer_size][str_values_size]){
uint16_t i = 0;
uint16_t j = 0;
uint16_t length = strlen(command);
int16_t Int_Values_Index = -1;
bool Int_Value_Flag = false;
char Int_Values[int_values_buffer_size][str_values_size];
for(i = 0; i < int_values_buffer_size; i++){
for(j = 0; j < str_values_size; j++){
Int_Values[i][j] = 0x00;
}
}
int16_t Str_Values_Index = -1;
bool Str_Value_Flag = false;
for(i = 0; i < length; i++){
switch(command[i]){
case ',': //Signifies integer value//
if(Int_Values_Index < int_values_buffer_size){
Int_Values_Index++;
Int_Value_Flag = true;
Str_Value_Flag = false;
j = 0;
}
command[i] = 0x00;
break;
case '-': //Signifies string value//
if(Str_Values_Index < str_values_buffer_size){
Str_Values_Index++;
Str_Value_Flag = true;
Int_Value_Flag = false;
j = 0;
}
command[i] = 0x00;
break;
default:
if(Int_Value_Flag){
Int_Values[Int_Values_Index][j] = command[i];
command[i] = 0x00;
j++;
}
if(Str_Value_Flag){
str_values_buffer[Str_Values_Index][j] = command[i];
command[i] = 0x00;
j++;
}
break;
}
}
//Convert integer strings to integers//
for(i = 0; i <= Int_Values_Index; i++){
int_values_buffer[i] = atoi(Int_Values[i]);
}
}
Function Call:
USART1_Command_Decode(USART1_Command, USART1_Command_Int_Values, MAX_COMMAND_INT_VALUES, MAX_COMMAND_STR_VALUES, MAX_COMMAND_STR_LENGTH, USART1_Command_Str_Values);
Thank you #P__J__ for the help!
EDIT:
I found the main problem with my original code, I was having problems with stack overflow because I was misunderstanding the allocation for stack and heap in Cross Studio. I had 256bytes of stack when I thought that I had more like 20KB. I allocated 16KB to stack and 8KB to heap, all the problems with malloc() and calloc() have disappeared along with the array writing issues. I apologize to everyone for the unnecessary question.

AES 128 with CBC-MAC in C

The code showing below is AES with CBC mode implementation. I am very new to the network security aspect. I am wondering how I can add the mac generation function upon the block and makes it as cbc-mac
static void GenerateDecryptionKey(uint8_t *key)
{
CRYCONLbits.CRYON = 0b1; //Turn module on
CRYCONHbits.KEYSRC = 0b000; //Select the key source (CRYKEY)
CRYCONLbits.OPMOD = 0b0010; //Select the operational mode (AES Decryption Key Expansion)
CRYCONLbits.CPHRSEL = 0b1; //Select the cipher (AES)
//(AES decryption key generation)
CRYCONHbits.KEYMOD = 0b00; //Set the key strength (128-bit key)
memcpy((void *)&CRYKEY0, key, 16); //Load the key into CRYKEY
//(128-bit key in this example)
CRYCONLbits.CRYGO = 0b1; //Start the encryption
while (CRYCONLbits.CRYGO == 0b1)
;
}
// For 128-bit key and 128-bit block size
void EncryptBlocks(
CIPHER_MODE mode,
uint8_t *key,
uint8_t *iv,
uint8_t *plaintext,
uint8_t *ciphertext,
int numblocks)
{
CRYCONLbits.CRYON = 1; //Turn module on
CRYCONHbits.KEYSRC = 0b0000; //Select the key source (CRYKEY)
CRYCONLbits.OPMOD = 0b0000; //Select operational mode (Encryption)
CRYCONLbits.CPHRSEL = 1; //Select cipher engine (AES)
CRYCONLbits.CPHRMOD = 0b001 ; //Select encryption mode
CRYCONHbits.KEYMOD = 0; //Set key strength to 128-bit
memcpy((void*)&CRYKEY0, key, 16); //Load the 128-bit key into CRYKEY
memcpy((void*)&CRYTXTB0, iv, 16); //Load the 128-bit initial vector (IV)
int i;
for (i = 0; i < numblocks; i += 16) {
//Load the next plaintext block into CRYTXTA
memcpy((void*)&CRYTXTA0, plaintext+ i, 16);
//Start the encryption
CRYCONLbits.CRYGO = 0b1;
// Wait for completion
while (CRYCONLbits.CRYGO == 0b1)
;
//Read the results out of CRYTXTB
memcpy(ciphertext+i, (void*)&CRYTXTB0, 16);
}
}
// For 128-bit key and 128-bit block size
void DecryptBlocks(
CIPHER_MODE mode,
uint8_t *key,
uint8_t *ciphertext,
uint8_t *plaintext,
int numblocks)
{
GenerateDecryptionKey(key);
CRYCONLbits.CRYON = 1; //Turn module on
CRYCONHbits.KEYSRC = 0b0000; //Select the key source (CRYKEY)
CRYCONLbits.OPMOD = 0b0001; //Select operational mode (Decryption)
CRYCONLbits.CPHRSEL = 1; //Select cipher engine (AES)
CRYCONLbits.CPHRMOD = 0b001; //Select decryption mode (CBC)
CRYCONHbits.KEYMOD = 0; //Set key strength to 128-bit
int i;
for (i = 0; i < numblocks; i+= 16) {
//Load the next plaintext block into CRYTXTA
memcpy((void*)&CRYTXTA0, plaintext+i, 16);
//Start the encryption
CRYCONLbits.CRYGO = 0b1;
// Wait for completion
while (CRYCONLbits.CRYGO == 0b1)
;
//Read the results out of CRYTXTB
memcpy(ciphertext+i, (void*)&CRYTXTB0, 16);
}
}
part of the test code is showing below
EncryptBlocks(mode, AES_KEY, 0, plaintext, ciphertext, numblocks);
//EncryptBlocks(mode, AES_KEY, 0, plaintext, ciphertext, numblocks);//iv=0; for ECB mode
//LED1 = 0;
printf("Encrypted block:");
for (i = 0; i < numblocks; i++) {
base = i*16;
printf("\n");
for (j = base; j < base+16; j++) {
printf(" %02X", ciphertext[j]);
last[0] = ciphertext[j];
}
}
printf("\n\n");
for (i = 0; i < 16; i++) {
iv[i] = 0;
}
for(i=0;i<sizeof(plaintext);i++)
plaintext[i] = 0;
DecryptBlocks(mode, AES_KEY, ciphertext, plaintext, numblocks);
printf("Decrypted block: ");
for (i = 0; i < numblocks; i++)
{
base = i*16;
printf("\n");
for (j = base; j < base+16; j++) {
printf(" %02X", plaintext[j]);
}
}
printf("\n");
}

One buttoned bandit slot machine - int function

I'm making one-buttoned bandit slot machine made on 3x 7 segment displays and 3x 74HC595 Shift Registers. Problem is that I want to have some kind of indicator that you won (or you partially won - 2 numbers are the same).
losLiczb(latchPin3, dataPin3, clockPin3, data3, liczba3); // liczba3 = in eg. 4
Serial.println("Wylosowana liczba to"); // "Generated number:"
Serial.println(liczba3); // liczba3 = 0
So, liczba1/liczba2/liczba3 is number which was generated in function losLiczb. Main problem is that liczba1/2/3 have assigned number inside function losLiczb (I can chceck correctness via Serial Read), but outside the number liczba1/2/3 is 0, thus program will always indicate that you won. Here is the whole program if you want (some of comments are in polish and are unnessecary,:
int latchPin1 = 5; //Pin connected to ST_CP of 74HC595
int clockPin1 = 4; //Pin connected to SH_CP of 74HC595
int dataPin1 = 6; //Pin connected to DS of 74HC595
int latchPin2 = 8;
int clockPin2 = 7;
int dataPin2 = 9;
int latchPin3 = 11; //11
int clockPin3 = 12; //12
int dataPin3 = 10; //8
int liczba1;
int liczba2;
int liczba3;
const int buttonPin = 2;
int statusPin = 3;
int buttonState = 0;
//holders for infromation you're going to pass to shifting function
byte data;
byte data1;
byte data2;
byte data3;
byte dataArray[10];
byte animacja[8];
byte dummy[1];
void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin1, OUTPUT);
pinMode(latchPin2, OUTPUT);
pinMode(latchPin3, OUTPUT);
pinMode(statusPin, OUTPUT);
pinMode(buttonPin, INPUT);
Serial.begin(9600);
//Arduino doesn't seem to have a way to write binary straight into the code
//so these values are in HEX. Decimal would have been fine, too.
// 00000000 - trzeba zapisywać w translatorze hex-bin w takiej postaci.
// Kolejno od prawej wartości odpowiadają kropce, a, b , c , d, e , f , g
// dataArray[2] = 0xB6; //11111100 FC
dataArray[0] = 0x7F;
dataArray[1] = 0x0C;
dataArray[2] = 0xB6;
dataArray[3] = 0x9E;
dataArray[4] = 0xCC;
dataArray[5] = 0xDA;
dataArray[6] = 0xFA;
dataArray[7] = 0x0E;
dataArray[8] = 0xFE;
dataArray[9] = 0xDE;
animacja[0] = 0x80; //g
animacja[1] = 0x20; //e
animacja[2] = 0x10; //d
animacja[3] = 0x08; //c
animacja[4] = 0x80; //g
animacja[5] = 0x40; //f
animacja[6] = 0x02; //a
animacja[7] = 0x04; //b
dummy[0] = 0x00;
randomSeed(analogRead(0));
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
anim();
} else {
idle();
digitalWrite(statusPin, LOW);
}
}
void idle(){
data = dummy[0];
digitalWrite(latchPin1, 0);
shiftOut(dataPin1, clockPin1, data);
digitalWrite(latchPin1, 1);
digitalWrite(latchPin2, 0);
shiftOut(dataPin2, clockPin2, data);
digitalWrite(latchPin2, 1);
digitalWrite(latchPin3, 0);
shiftOut(dataPin3, clockPin3, data);
digitalWrite(latchPin3, 1);
}
// Funkcja odpowiedzialna za animację
void anim(){
for (int p =0; p < 3; p++){
for (int i = 0; i < 8; i++) {
data = animacja[i];
digitalWrite(latchPin1, 0);
shiftOut(dataPin1, clockPin1, data);
digitalWrite(latchPin2, 0);
shiftOut(dataPin2, clockPin2, data);
digitalWrite(latchPin3, 0);
shiftOut(dataPin3, clockPin3, data);
digitalWrite(latchPin1, 1);
digitalWrite(latchPin2, 1);
digitalWrite(latchPin3, 1);
delay(100);
}
}
losLiczb(latchPin1, dataPin1, clockPin1, data1, liczba1);
Serial.println("Wylosowana liczba to");
Serial.println(liczba1);
for (int p =0; p < 2; p++){
for (int i = 0; i < 8; i++) {
data = animacja[i];
digitalWrite(latchPin2, 0);
shiftOut(dataPin2, clockPin2, data);
digitalWrite(latchPin3, 0);
shiftOut(dataPin3, clockPin3, data);
digitalWrite(latchPin2, 1);
digitalWrite(latchPin3, 1);
delay(100);
}
}
losLiczb(latchPin2, dataPin2, clockPin2, data2, liczba2);
Serial.println("Wylosowana liczba to");
Serial.println(liczba2);
for (int p =0; p < 2; p++){
for (int i = 0; i < 8; i++) {
data = animacja[i];
digitalWrite(latchPin3, 0);
shiftOut(dataPin3, clockPin3, data);
digitalWrite(latchPin3, 1);
delay(100);
}
}
losLiczb(latchPin3, dataPin3, clockPin3, data3, liczba3);
Serial.println("Wylosowana liczba to");
Serial.println(liczba3);
if (data1 == data2){
digitalWrite(statusPin, HIGH);
} else {
digitalWrite(statusPin, LOW);
}
delay(5000);
}
//Funckja odpowiedzialna za wylosowanie liczby
int losLiczb(int myLatchPin, int myDataPin, int myClockPin, int myData, int myLiczba) {
//load the light sequence you want from array
int j = random(0, 9);
myLiczba = j;
myData = dataArray[j];
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(myLatchPin, 0);
//move 'em out
shiftOut(myDataPin, myClockPin, myData);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(myLatchPin, 1);
Serial.println("Wylosowana liczba to");
Serial.println(myLiczba);
}
// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut�
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
//if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Sets the pin to HIGH or LOW depending on pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
Pass the values you want the function to output by reference or by pointer.
void Wrong(int a) {
a = 10;
}
void Right(int& a) {
a = 20;
}
void Right(int* pA) {
*pA = 30;
}
int a = 0;
Wrong(a); printf("%d ", a);
Right(a); printf("%d ", a);
Right(&a); printf("%d\n", a);
output will be 0 20 30

Resources