Si bien es cierto, ya habíamos realizado una serie de tarjetas plc con microcontroladores de atmel y de esp32, pero aún no habíamos logrado hacer con los microcontroladores de stm32. Asi que hoy vamos a desbloquear ese miedo y haremos un plc con un microcontrolador de la familia stm32. entonces, empezaremos haciendo un plc específicamente con el microcontrolador stm32F103C8T6, que es un microcontrolador básico de esta familia, y según vamos avanzando con las versiones, iremos desarrollando con otros micros más potentes de esta línea.
DATOS TECNICOS

- Tensión de alimentación……………………….…………24VDC
- Corriente de alimentación………………….……………90mA
- Entadas digitales 15-24VDC……………………….……8
- Salidas RLY…………………………………………………………6
-
- Tensión AC…………..……….………………….….……250V
- Corriente AC…………………………………………….5A
- Tensión DC………………………………………………30V
- Corriente DC……………………………………………5A
-
- Salidas PMW (24V)……………………………………………………………3
- Entorno de programación………………………..………..STM32 cube, Arduino IDE
- Condiciones ambientales min……………………….….-40°
- Condiciones ambientales max…………………..……….150°
- Empotrable………………………………….……………………Sí
- Puerto Usb…………………………………………………………………SÍ
- Comunicacion I2C……………………………………………………..Sí
LISTA DE MATERIALES

| No. | Quantity | Comment | Designator | Footprint | Value | Manufacturer Part | Supplier Part | Supplier |
| 1 | 2 | 470uF | C1,C17 | CAP-SMD_BD10.0-L10.3-W10.3-LS11.3-FD | 470uF | VT1V471M1010 | C310845 | LCSC |
| 2 | 2 | 1uF | C2,C18 | C1206 | 1uF | CL31B105KBHNNNE | C1848 | LCSC |
| 3 | 26 | 100nF | C3,C4,C5,C6,C7,C8,C9,C10,C11,C12, C13,C15,C16,C19,C21,C22,C23,C24, C25,C26,C27,C28,C32,C33,C34,C35 |
C0603 | 100nF | CC0603KRX7R9BB104 | C14663 | LCSC |
| 4 | 2 | 220uF | C14,C20 | CAP-SMD_BD6.3-L6.6-W6.6-LS7.2-R-RD | 220uF | RVE1C221M0607 | C99836 | LCSC |
| 5 | 1 | 1uF | C29 | C0603 | 1uF | CL10A105KB8NNNC | C15849 | LCSC |
| 6 | 4 | 20pF | C30,C31,C36,C37 | C0603 | 20pF | CL10C200JB8NNNC | C1648 | LCSC |
| 7 | 2 | HCZZ0126-4 | CN1,CN2 | CONN-TH_XH2.54-4P | HCZZ0126-4 | C7433754 | LCSC | |
| 8 | 7 | SS210 | D1,D2,D3,D4,D7,D8,D9 | SMA_L4.3-W2.6-LS5.2-RD | SS210 | C14996 | LCSC | |
| 9 | 2 | BZT52C3V3 | D5,D6 | SOD-123_L2.7-W1.6-LS3.7-RD | BZT52C3V3 | C173413 | LCSC | |
| 10 | 3 | M7 | D10,D11,D12 | SMA_L4.3-W2.6-LS5.2-RD | M7 | C95872 | LCSC | |
| 11 | 6 | 1N4148WS | D13,D14,D15,D16,D17,D18 | SOD-323_L1.8-W1.3-LS2.5-RD | 1N4148WS | C2128 | LCSC | |
| 12 | 1 | BSMD1206-100-24V | F1 | F1206 | BSMD1206-100-24V | C910830 | LCSC | |
| 13 | 1 | ZX-PZ2.54-2-3PZZ | H1 | HDR-TH_6P-P2.54-V-M-R2-C3-S2.54-1 | ZX-PZ2.54-2-3PZZ | C7501274 | LCSC | |
| 14 | 1 | PZ254V-11-04P | H2 | HDR-TH_4P-P2.54-V-M | PZ254V-11-04P | C2691448 | LCSC | |
| 15 | 2 | 68uH | L1,L2 | IND-SMD_L7.1-W6.6-1 | 68uH | PSPMAA0605H-680M-IGF | C2983094 | LCSC |
| 16 | 18 | KT-0805G | LED1,LED2,LED3,LED4,LED5,LED6,LED7, LED8,LED9,LED10,LED11,LED12,LED13, LED14,LED15,LED16,LED17,LED18 |
LED0805-R-RD | KT-0805G | C2297 | LCSC | |
| 17 | 10 | WJ128V-5.0-2P | P1,P2,P6,P7,P8,P9,P10,P11,P12,P13 | CONN-TH_2P-P5.00_WJ128V-5.0-2P | WJ128V-5.0-2P | C8269 | LCSC | |
| 18 | 3 | WJ128V-5.0-3P | P3,P4,P5 | CONN-TH_3P-P5.00_WJ128V-5.0-3P | WJ128V-5.0-3P | C8270 | LCSC | |
| 19 | 3 | AO3401A | Q1,Q2,Q3 | SOT-23_L2.9-W1.3-P1.90-LS2.4-BR | AO3401A | C15127 | LCSC | |
| 20 | 6 | MMBT3904 | Q4,Q5,Q6,Q7,Q8,Q9 | SOT-23-3_L2.9-W1.3-P1.90-LS2.4-BR | MMBT3904 | C20526 | LCSC | |
| 21 | 10 | 10kΩ | R1,R2,R3,R4,R5,R6,R7,R8,R9,R10 | R1206 | 10kΩ | 1206W4F1002T5E | C17902 | LCSC |
| 22 | 2 | 680Ω | R11,R12 | R0805 | 680Ω | 0805W8F6800T5E | C17798 | LCSC |
| 23 | 2 | 330Ω | R13,R14 | R0805 | 330Ω | 0805W8F3300T5E | C17630 | LCSC |
| 24 | 24 | 10kΩ | R15,R16,R17,R18,R19,R20,R21,R22, R40,R42,R43,R44,R55,R56,R57,R58, R59,R60,R67,R68,R69,R70,R71,R72 |
R0603 | 10kΩ | 0603WAF1002T5E | C25804 | LCSC |
| 25 | 23 | 1kΩ | R23,R24,R25,R26,R27,R28,R29,R30, R31,R32,R33,R34,R35,R48,R50,R52, R54,R73,R74,R75,R76,R77,R78 |
R0603 | 1kΩ | 0603WAF1001T5E | C21190 | LCSC |
| 26 | 3 | 100kΩ | R36,R37,R41 | R0603 | 100kΩ | 0603WAF1003T5E | C25803 | LCSC |
| 27 | 2 | 20Ω | R38,R39 | R0603 | 20Ω | 0603WAF200JT5E | C22950 | LCSC |
| 28 | 9 | 220Ω | R45,R46,R47,R61,R62,R63,R64,R65,R66 | R0603 | 220Ω | 0603WAF2200T5E | C22962 | LCSC |
| 29 | 9 | 4.7kΩ | R49,R51,R53,R79,R80,R81,R82,R83,R84 | R0805 | 4.7kΩ | 0805W8F4701T5E | C17673 | LCSC |
| 30 | 6 | RC-124DM1 | RLY1,RLY2,RLY3,RLY4,RLY5,RLY6 | RELAY-TH_RC-XXXXM | RC-124DM1 | C358574 | LCSC | |
| 31 | 1 | TS-1187A-B-A-B | SW1 | SW-SMD_4P-L5.1-W5.1-P3.70-LS6.5-TL-2 | TS-1187A-B-A-B | C318884 | LCSC | |
| 33 | 17 | TLP127(TPL,U,F) | U1,U2,U3,U4,U5,U6,U7,U8,U13,U14, U15,U16,U17,U18,U19,U20,U21 |
SOP-4_L3.6-W4.4-P2.54-LS7.0-BR | TLP127(TPL,U,F) | C5001 | LCSC | |
| 34 | 1 | LM2594M-5.0 | U9 | SOP-8_L4.9-W3.9-P1.27-LS6.0-BL | LM2594M-5.0 | C2904795 | LCSC | |
| 35 | 1 | LM2594M-3.3 | U10 | SOP-8_L4.9-W3.9-P1.27-LS6.0-BL | LM2594M-3.3 | C3029048 | LCSC | |
| 36 | 1 | SN74HC541PWR | U11 | TSSOP-20_L6.5-W4.4-P0.65-LS6.4-BL | SN74HC541PWR | C6758 | LCSC | |
| 37 | 1 | STM32F103C8T6 | U12 | LQFP-48_L7.0-W7.0-P0.50-LS9.0-BL | STM32F103C8T6 | C8734 | LCSC | |
| 38 | 2 | SN74HC14PWR | U22,U23 | TSSOP-14_L5.0-W4.4-P0.65-LS6.4-BL | SN74HC14PWR | C6821 | LCSC | |
| 39 | 1 | LM358DR2G | U24 | SOIC-8_L5.0-W4.0-P1.27-LS6.0-BL | LM358DR2G | C7950 | LCSC | |
| 40 | 1 | MICRO 4P DIP | USB1 | MINI-USB-SMD_MICRO-4P-DIP | MICRO 4P DIP | C456008 | LCSC | |
| 41 | 1 | 32.768kHz | X1 | FC-135R_L3.2-W1.5 | 32.768kHz | Q13FC13500004 | C32346 | LCSC |
| 42 | 1 | 8MHz | X2 | CRYSTAL-SMD_L5.0-W3.2 | 8MHz | X50328MSB2GI | C115962 | LCSC |
CODIGO

TEST ENTRADAS DIGITALES Y SALIDAS A RELAY
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
GPIO_PinState buttonStates[6];
GPIO_TypeDef* buttonPorts[6] = {GPIOB, GPIOB, GPIOB, GPIOB, GPIOB, GPIOB};
uint16_t buttonPins[6] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_10, GPIO_PIN_11, GPIO_PIN_12};
GPIO_TypeDef* ledPorts[6] = {GPIOB, GPIOA, GPIOA, GPIOB, GPIOB, GPIOB};
uint16_t ledPins[6] = {GPIO_PIN_15, GPIO_PIN_8, GPIO_PIN_15, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5};
for (int i = 0; i < 6; i++) {
buttonStates[i] = HAL_GPIO_ReadPin(buttonPorts[i], buttonPins[i]);
HAL_GPIO_WritePin(ledPorts[i], ledPins[i], (buttonStates[i] == GPIO_PIN_SET) ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8|GPIO_PIN_15, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : PB15 PB3 PB4 PB5 */
GPIO_InitStruct.Pin = GPIO_PIN_15|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : PA8 PA15 */
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
LECTURA ANALOGICA Y SALIDA PWM (LCD I2C)
#include "main.h"
#include "adc.h"
#include "i2c.h"
#include "tim.h"
#include "gpio.h"
#include "Lcd_i2c.h"
#include "stdio.h"
char buf_lcd[18];
uint8_t duty_pwm = 0;
uint8_t porcentaje_duty = 0;
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM2_Init();
MX_I2C1_Init();
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,0);
Lcd_Init();
while (1)
{
HAL_ADC_Start(&hadc1);
int valor_adc = HAL_ADC_GetValue(&hadc1);
duty_pwm = (uint8_t)((valor_adc*99)/4095);
porcentaje_duty = (uint8_t)((duty_pwm*100)/99);
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,duty_pwm);
Lcd_Set_Cursor(1,1);
sprintf(buf_lcd, "Analog in: %u ", valor_adc);
Lcd_Send_String(buf_lcd);
Lcd_Set_Cursor(2,1);
sprintf(buf_lcd, "pwm: %u ", duty_pwm);
Lcd_Send_String(buf_lcd);
HAL_Delay(50);
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */



