Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 3 juni 2021, 16:41:45
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Kod: Markera allt
/* Callbacks for external interrupt */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
/* We have pressed on the touch screen -> TS_IRQ falling edge */
if(GPIO_Pin == TS_IRQ_Pin) {
TSC2046_TS_IRQ();
}
}
Kod: Markera allt
TSC2046_TS_IRQ();
Kod: Markera allt
static uint16_t TSC2046_SendCommand(uint8_t cmd) {
uint8_t lcdBuf[3] = { 0, 0, 0 };
uint16_t return16 = 0;
HAL_GPIO_WritePin(lcd.TOUCH_CS_PORT, lcd.TOUCH_CS_PIN, GPIO_PIN_RESET);
lcdBuf[0] = cmd;
HAL_SPI_Transmit(lcd.touchSpi, lcdBuf, 1, 10); // <----- HÄR är problemet.
//Wait for response (3 ms)
//HAL_Delay(3);
if (HAL_SPI_Receive(lcd.touchSpi, &lcdBuf[1], 2, 10) == HAL_OK) {
return16 = (lcdBuf[1] << 4) + (lcdBuf[2] >> 4);
} else {
return16 = 0;
}
HAL_GPIO_WritePin(lcd.TOUCH_CS_PORT, lcd.TOUCH_CS_PIN, GPIO_PIN_SET);
return return16;
}
Kod: Markera allt
// Send TSC2046 Command and wait for a response
static uint16_t TSC2046_SendCommand(uint8_t cmd) {
uint8_t lcdBuf[3] = { 0, 0, 0 };
uint16_t return16 = 0;
HAL_GPIO_WritePin(lcd.TOUCH_CS_PORT, lcd.TOUCH_CS_PIN, GPIO_PIN_RESET);
lcdBuf[0] = cmd;
HAL_SPI_Transmit(lcd.touchSpi, lcdBuf, 1, 10);
//Wait for response (3 ms)
//HAL_Delay(3);
if (HAL_SPI_Receive(lcd.touchSpi, &lcdBuf[1], 2, 10) == HAL_OK) {
return16 = (lcdBuf[1] << 4) + (lcdBuf[2] >> 4);
} else {
return16 = 0;
}
HAL_GPIO_WritePin(lcd.TOUCH_CS_PORT, lcd.TOUCH_CS_PIN, GPIO_PIN_SET);
return return16;
}
// Get x-axis raw touch 12-bit value
static uint16_t TSC2046_getRaw_X() {
return TSC2046_SendCommand(CMD_X_AXIS | lcd.CMD_Default);
}
// Get y-axis raw touch 12-bit value
static uint16_t TSC2046_getRaw_Y() {
return TSC2046_SendCommand(CMD_Y_AXIS | lcd.CMD_Default);
}
/* Get z-axis raw touch 12-bit value
static uint16_t TSC2046_getRaw_Z() {
return TSC2046_SendCommand(CMD_Z_AXIS | lcd.CMD_Default);
}*/
// Print calibration points
// Top-Left corner point
static void TSC2046_TL_point() {
ILI9341_fillCircle(1, 1, 3, COLOR_RED);
ILI9341_printText("Press here", 20, 30, COLOR_RED, COLOR_RED, 1);
}
// Bottom-Right corner point
static void TSC2046_BR_point() {
ILI9341_fillCircle(lcd.myTS_Calibrate.Width - 1, lcd.myTS_Calibrate.Height - 1, 3, COLOR_RED);
ILI9341_printText("Press here", lcd.myTS_Calibrate.Width - 80, lcd.myTS_Calibrate.Height - 40, COLOR_RED, COLOR_RED, 1);
}
// Poll for touch status
static void TSC2046_GetRawTouch() {
// Assign raw touch based on orientation
switch (lcd.ScreenOrientation) {
case 1:
lcd.localRawTouch.x_touch = 4095 - TSC2046_getRaw_X();
lcd.localRawTouch.y_touch = TSC2046_getRaw_Y(lcd);
lcd.myTS_Calibrate.Width = 230;
lcd.myTS_Calibrate.Height = 320;
break;
case 2:
lcd.localRawTouch.x_touch = 4095 - TSC2046_getRaw_Y();
lcd.localRawTouch.y_touch = 4095 - TSC2046_getRaw_X();
lcd.myTS_Calibrate.Width = 320;
lcd.myTS_Calibrate.Height = 240;
break;
case 3:
lcd.localRawTouch.x_touch = TSC2046_getRaw_X();
lcd.localRawTouch.y_touch = 4095 - TSC2046_getRaw_Y();
lcd.myTS_Calibrate.Width = 230;
lcd.myTS_Calibrate.Height = 320;
break;
case 4:
lcd.localRawTouch.x_touch = TSC2046_getRaw_Y();
lcd.localRawTouch.y_touch = TSC2046_getRaw_X();
lcd.myTS_Calibrate.Width = 320;
lcd.myTS_Calibrate.Height = 240;
break;
}
// These are for the calibration
lcd.myRawTouchDef.x_touch = lcd.localRawTouch.x_touch;
lcd.myRawTouchDef.y_touch = lcd.localRawTouch.y_touch;
}
// Calibrate resistive touch panel
void TSC2046_Calibrate() {
// Set rotation
ILI9341_setRotation(2);
// For every time we touch the LCD, then TS_IRQ pin falling edge . Interrupt is called
lcd.calibration_mode = 1;
lcd.myTS_Calibrate.TL_X = 0;
lcd.myTS_Calibrate.TL_Y = 0;
lcd.myTS_Calibrate.BR_X = 0;
lcd.myTS_Calibrate.BR_Y = 0;
lcd.myRawTouchDef.y_touch = 0;
lcd.myRawTouchDef.x_touch = 0;
// Get Top-Left corner calibration coordinate
TSC2046_TL_point(lcd);
lcd.myTsData.isPressed = 0;
while (1) {
if (lcd.myTsData.isPressed) {
for (uint8_t i = 0; i < 10; i++) {
TSC2046_GetRawTouch(lcd);
lcd.myTS_Calibrate.TL_X += lcd.myRawTouchDef.x_touch;
lcd.myTS_Calibrate.TL_Y += lcd.myRawTouchDef.y_touch;
}
break;
}
HAL_Delay(10);
}
HAL_Delay(1000);
// Get Bottom-Right corner calibration coordinate
TSC2046_BR_point(lcd);
lcd.myTsData.isPressed = 0;
while (1) {
if (lcd.myTsData.isPressed) {
for (uint8_t i = 0; i < 10; i++) {
TSC2046_GetRawTouch(lcd);
lcd.myTS_Calibrate.BR_X += lcd.myRawTouchDef.x_touch;
lcd.myTS_Calibrate.BR_Y += lcd.myRawTouchDef.y_touch;
}
break;
}
HAL_Delay(10);
}
lcd.myTS_Calibrate.TL_X *= 0.1;
lcd.myTS_Calibrate.TL_Y *= 0.1;
lcd.myTS_Calibrate.BR_X *= 0.1;
lcd.myTS_Calibrate.BR_Y *= 0.1;
// Calculate scalar
lcd.myTS_Calibrate.Scale_X = (lcd.myTS_Calibrate.Width + 0.0f) / (lcd.myTS_Calibrate.BR_X - lcd.myTS_Calibrate.TL_X + 0.0f);
lcd.myTS_Calibrate.Scale_Y = (lcd.myTS_Calibrate.Height + 0.0f) / (lcd.myTS_Calibrate.BR_Y - lcd.myTS_Calibrate.TL_Y + 0.0f);
// Calculate bias
lcd.myTS_Calibrate.Bias_X = -1 - lcd.myTS_Calibrate.Scale_X * lcd.myTS_Calibrate.TL_X; // -1 is for bias. Change this so you have 100% accuracy at center of the LCD
lcd.myTS_Calibrate.Bias_Y = -1 - lcd.myTS_Calibrate.Scale_Y * lcd.myTS_Calibrate.TL_Y; // -1 is for bias. Change this so you have 100% accuracy at center of the LCD
// Calibration done
lcd.calibration_mode = 0;
lcd.myTsData.isPressed = 0;
}
// Get touch screen data when calibration is already made
void TSC2046_GetTouchData() {
uint16_t temp16x = 0, temp16y = 0;
lcd.calibration_mode = 0;
// Read touch data
for (uint8_t i = 0; i < 10; i++) {
TSC2046_GetRawTouch(lcd);
temp16x += lcd.localRawTouch.x_touch;
temp16y += lcd.localRawTouch.y_touch;
}
lcd.localRawTouch.x_touch = temp16x * 0.1;
lcd.localRawTouch.y_touch = temp16y * 0.1;
// X-axis value
lcd.myTsData.X = lcd.myTS_Calibrate.Scale_X * lcd.localRawTouch.x_touch + lcd.myTS_Calibrate.Bias_X;
// Y-axis value
lcd.myTsData.Y = lcd.myTS_Calibrate.Scale_Y * lcd.localRawTouch.y_touch + lcd.myTS_Calibrate.Bias_Y;
}
void TSC2046_TS_IRQ() {
if (lcd.calibration_mode == 1) {
lcd.myTsData.isPressed = 1; // Only call this because we want raw touch screen XY-positions
} else {
lcd.myTsData.isPressed = 1;
TSC2046_GetTouchData(lcd); // In this case, we have already calibrated the LCD
}
}
Kod: Markera allt
/* Callbacks for external interrupt */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
/* We have pressed on the touch screen -> TS_IRQ falling edge */
if(GPIO_Pin == TS_IRQ_Pin) {
lcd.myTsData.isPressed = 1;
}
}