Merhaba,
Python tarafında slider ile değişen 4 açı değerim var, bu değerler bir dizi içerisinde seri porttan sırayla gönderiliyor.
İlk slider->30 ise ve diğerleri 0 ise de gönderiliyor. Stm tarafında kesme olan kısımdaki kodlarım şu şekilde: (Değişkenleri yukarda tanımlı sadece kod bloğunu atıyorum)
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
if ((rx_data != '\n') && (cnt < MAX_STRLEN))
{ //rx_data boş karakter değil ve maximum karakter sayısı aşılması ise
data[cnt] = rx_data;
cnt++;
}
else
{ // boş karakter gelmemiş ve maksimum karakter kullanılmışsa
cnt = 0;
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
Şimdi gelelim sorunda, Pyhton tarafından aldığım 4 değer sırayla, gelmiyor yani 2. slider'ın hareketini 1. motorda görüyorum aslında böyle olmamalıydı.
Data dizisindeki 4 elemanı aşağıda 4 motora gönderiyorum.
Burada nasıl sırayla alabilirim ?
Kodların tamamı şu şekilde:
#include "main.h"
#include "common.h"
#include "io_periph_defs.h"
#include "conf.h"
// Kanal 2 de 4 tane Chanel var CH1-CH2-CH3-CH4 4 servo kullanacağımızdan kullanımı kolay olacak
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
void USART1_Init(void);
void led_toggle(void);
void servo_change(void);
static uint8_t cnt = 0;
void servo_controller(uint16_t s1, uint16_t s2, uint16_t s3, uint16_t s4);
void angle_convert_dutycyle(uint16_t angl1, uint16_t angl2, uint16_t angl3, uint16_t angl4);
uint16_t dc, dc2, dc3, dc4;
uint16_t srv1, srv2, srv3, srv4;
static unsigned int USART_angle;
//static unsigned int Led_state = 0;
#define MAX_STRLEN 4
volatile char data[MAX_STRLEN + 1];
char Usart_data;
int main()
{
Usart1_init();
SysTick_Config(SystemCoreClock / 1000);
// init_pin(DEBUG_LED_PORT, DEBUG_LED_PIN2, GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL);
// GPIO_ResetBits(DEBUG_LED_PORT, DEBUG_LED_PIN2); // basılmadığı durumda reset durumundadır.
// Delay(500);
// GPIO_ResetBits(DEBUG_LED_PORT, DEBUG_LED_PIN);
SERVO_GPIO_Init();
SERVO_PWM_Init();
// init_pin(DEBUG_LED_PORT, DEBUG_LED_PIN, GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP); //led bilgileri tanımlandı.
USART1_IRQHandler();
while (1)
{
// if (data[0] != '\n')
// {
// servo_change();
// }
// Delay(500);
}
}
void SERVO_GPIO_Init(void) // Servo pin ayarları
{
GPIO_InitTypeDef GPIO_InitStructure;
//TIM2-PA0
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM2'de CH_1 pini PA0 olduğu için ilk servo ona göre ayarlandı
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_1); // PA0'ın AF_1 kısmında TIM2 ve CH_1 aktif
//TIM2-PA1
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM2 CH_2 PA1'de tanımlı
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_1); // TIM2 ve CH2 bu kısımda tanımlı
//TIM2-PA2
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //TIM2 CH_3 PA3'de tanımlı
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1); // TIM2 ve CH3 bu kısımda tanımlı
//TIM2-PA3
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //TIM2 CH_2 PA3'de tanımlı
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1); // TIM2 ve CH2 bu kısımda tanımlı
}
void SERVO_PWM_Init(void) //servo pwm-timer ayarları
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 19999; //arr degeri
TIM_TimeBaseStructure.TIM_Prescaler = 84; //PrescalerValue; 84
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
// Kanal Ayarlarını yaptığımız kısım
//CH1 için
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM2, ENABLE);
// TIM2 de Chanel 2 ayarlarını aktif ediyoruz
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 2; //CCR_Val;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_Cmd(TIM2, ENABLE);
//CH3
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 3; //CCR_Val;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_Cmd(TIM2, ENABLE);
//CH4
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 4; //CCR_Val;
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_Cmd(TIM2, ENABLE);
}
// void led_toggle()
// {
// GPIO_SetBits(DEBUG_LED_PORT, DEBUG_LED_PIN);
// }
// void led_off()
// {
// GPIO_ResetBits(DEBUG_LED_PORT, DEBUG_LED_PIN);
// }
void Usart1_init(void)
{
// Usart ayarlarını yaptığımız kısım
GPIO_InitTypeDef GPIO_InitStructure; // Tx ve Rx ayarları için oluşturduğumuz struct
USART_InitTypeDef USART_InitStrutcure; // Usart ayarları için oluşturduğumuz struct
NVIC_InitTypeDef NVIC_InitStructure; //nvic ayarları için oluşturulan struct
// USART için Clock ayarlarını yapıyoruz
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// Datasheet bilgilerine baktığımızda A9-> TX, A10->RX pinleri olarak kullanılıyor.
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // 9 ve 10. pinleri belirttik
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); // A portu olduğunu belirttik
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); // datasheetinde USART1 için AF değeri 7 olarak verilmiş
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
// USART Ayarlamaları
USART_InitStrutcure.USART_BaudRate = 9600; //iletişim hızı
USART_InitStrutcure.USART_WordLength = USART_WordLength_8b; // kaç bitlik veri gönderileceği bilgisi
USART_InitStrutcure.USART_Parity = USART_Parity_No;
USART_InitStrutcure.USART_StopBits = USART_StopBits_1;
USART_InitStrutcure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStrutcure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStrutcure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE); // Usart Aktif
// //Bir kesme oluşturacağımız için kesme ayarlarını yapmamız gerekiyor
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //USART1 in kesmesi olduğunu belirttik
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_Init(&NVIC_InitStructure);
}
void USART1_IRQHandler(void)
{
// USART_ClearITPendingBit(USART1, USART_IT_RXNE);
// USART_angle = (unsigned int)USART_ReceiveData(USART1);
//receive a char
// char data = USART_ReceiveData(USART1); //receive a char
// // char data = USART_ReceiveData(USART1); //receive a char
// if (data == '\r' || data == '\n')
// {
// if (rx_index != 0)
// {
// memcpy((void *)line_buffer, rx_buffer, rx_index);
// line_buffer[rx_index] = 0;
// line_valid = 1;
// data = (unsigned int)USART_angle;
// rx_index = 0;
// USART_PutString("data geldi");
// }
// }
// else
// {
// if (rx_index == LINEMAX)
// rx_index = 0;
// rx_buffer[rx_index++] = data;
// }
/*
*/
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
// char buf[100];
// uint16_t rx_data = USART_ReceiveData(USART1);
// sprintf(buf, "Incoming Byte is: %d\r\n", rx_data);
// USART_PutString(buf);
if (rx_data = 0xAA)
GPIO_SetBits(DEBUG_LED_PORT, DEBUG_LED_PIN2);
else if (rx_data = 0x55)
GPIO_ResetBits(DEBUG_LED_PORT, DEBUG_LED_PIN2);
if ((rx_data != '\n') && (cnt < MAX_STRLEN))
{ //rx_data boş karakter değil ve maximum karakter sayısı aşılması ise
data[cnt] = rx_data;
cnt++;
}
else
{ // boş karakter gelmemiş ve maksimum karakter kullanılmışsa
cnt = 0;
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
void servo_change(void)
{
srv1 = data[0];
srv2 = data[1];
srv3 = data[2];
srv4 = data[3];
servo_controller(srv1, srv2, srv3, srv4);
}
void angle_convert_dutycyle(uint16_t angl1, uint16_t angl2, uint16_t angl3, uint16_t angl4)
{
char buf[100];
float tmp1 = ((float)angl1 / 180.0f);
dc = ((tmp1 + 1.0f) * 1000.0f);
sprintf(buf, "1.Servo Angle is: %d , DC: %7.2f\r\n", angl1, ((tmp1 + 10.0f) * 100.0f));
USART_PutString(buf);
char buf2[100];
float tmp2 = ((float)angl2 / 180.0f);
dc2 = ((tmp1 + 1.0f) * 1000.0f);
sprintf(buf2, "2.Servo Angle is: %d , DC: %7.2f\r\n", angl2, ((tmp2 + 10.0f) * 100.0f));
USART_PutString(buf2);
char buf3[100];
float tmp3 = ((float)angl3 / 180.0f);
dc3 = ((tmp3 + 1.0f) * 1000.0f);
sprintf(buf3, "3.Servo Angle is: %d , DC: %7.2f\r\n", angl3, ((tmp3 + 10.0f) * 100.0f));
USART_PutString(buf3);
char buf4[100];
float tmp4 = ((float)angl4 / 180.0f);
dc4 = ((tmp4 + 1.0f) * 1000.0f);
sprintf(buf4, "4.Servo Angle is: %d , DC: %7.2f\r\n", angl4, ((tmp4 + 10.0f) * 100.0f));
USART_PutString(buf4);
}
void servo_controller(uint16_t s1, uint16_t s2, uint16_t s3, uint16_t s4)
{
angle_convert_dutycyle(s1, s2, s3, s4);
TIM2->CCR1 = dc;
Delay(300);
TIM2->CCR2 = dc2;
Delay(300);
TIM2->CCR3 = dc3;
Delay(300);
TIM2->CCR4 = dc4;
Delay(300);
}
static void USART_SendString(USART_TypeDef *USARTx, char *s)
{
while (*s)
{
while (!USART_GetFlagStatus(USARTx, USART_FLAG_TC))
;
USART_SendData(USARTx, *s);
s++;
}
}
void USART_PutString(char *s)
{
// Send a string
while (*s)
{
USART_PutChar(*s++);
}
}
void USART_PutChar(char c)
{
// Wait until transmit data register is empty
while (!USART_GetFlagStatus(USART1, USART_FLAG_TXE))
;
// Send a char using USART1
USART_SendData(USART1, c);
}
Sorunu çözdüm. Merak eden olursa nasıl olduğunu açıklayabilirim
Merak eden olursa nasıl olduğunu açıklayabilirm ne demek?
Pakete ekleyip alman daha doğru olur.
[X][Y][4 BYTE DATA][Z]
burada x, y, z senin belirlediğin sabit bir karakter.
Alıcı tarafta
x geldiyse y yi bekle
y geldiyse 4 byte al
ve z yi bekle
şeklinde olabilir.
Alıntı yapılan: MC_Skywalker - 25 Ağustos 2017, 20:24:40
Merak eden olursa nasıl olduğunu açıklayabilirm ne demek?
Cevap yazan olmadığına göre, ilgilenen olmadığını düşündüm ama aynı sorunu yaşayan olursa açıklarım demek
Alıntı yapılan: baran123 - 25 Ağustos 2017, 20:30:52
Pakete ekleyip alman daha doğru olur.
[X][Y][4 BYTE DATA][Z]
burada x, y, z senin belirlediğin sabit bir karakter.
Alıcı tarafta
x geldiyse y yi bekle
y geldiyse 4 byte al
ve z yi bekle
şeklinde olabilir.
Dizi olarak aldığım için. Python tarafında dizi sayısını 1 artırıp, son diziyi boş tanımladığımda hata düzeldi.
Peki bu şekilde bir paketi nasıl tanımlayabilirim ? Tam olarak bilgim yok, bu yöntemin bir adı var mı ?
Bu standart bir paketlemedir.
Haberleşme protokollerinin hepsinde veriler paketlenir.
Başın sabit bir karakter koyarsınız bu karakter gelince tamam benim verilerim geliyor diyebilirsiniz.
Verileri aldıktan sonra sonunda ise yine sabit bir karakterle verinin bittiğini anlarsınız.
Böylece hem verinin güvenliği bir puan artmış olur hemde kendi haberleşme katmanınızı tasarlamış olursunuz.
Bu yapıya geliştiren ise paket içerisine "CheckSum, CRC" tarzı kontroller eklemektir.
Bunu kullanmazsanız ne olur ona bakalım.
ROBOT kelimesini göndereceksiniz.
Verici yolluyor.
Fakat alan taraf bir problemden dolayı ilk karakteri alamadı ve gecikti, ne olur ?
OBOT olarak okuduğunuz veriyi yanlış değerlendirirsiniz ve problem oluşur.
Bu yüzden önce sabit 2 tane karakter yollanır
[X][Y] olsun bunlar
Sonra verinin uzunluğu yollansın (Daha iyi oldu artık veri uzunluğu dinamik)
[L] diyelim bunada.
Sonra L uzunluğunda veri olsun
[ DATA(L) ]
Hadi birde CRC ekleyelim CRC16 olsun
[CRC16] (2 BYTE)
ve son olarak paket sonu karakteri.
[Z] olsun.
[X] [Y] [L BYTE DATA] [CRC16] [Z]
Alıcı taraf artık paketi alıp işler orasını sana bırakıyorum.
Bunu biraz daha geliştirip birde cevap paketi yapabilirsin.
Örneğin veriyi aldım veya alamadım bilgisi.
Hatta alamadıysa tekrar gönder gibi bir yapı daha hoş olur.
vs vs ...
Alıntı yapılan: baran123 - 28 Ağustos 2017, 09:18:59
Bu standart bir paketlemedir.
Haberleşme protokollerinin hepsinde veriler paketlenir.
Başın sabit bir karakter koyarsınız bu karakter gelince tamam benim verilerim geliyor diyebilirsiniz.
Verileri aldıktan sonra sonunda ise yine sabit bir karakterle verinin bittiğini anlarsınız.
Böylece hem verinin güvenliği bir puan artmış olur hemde kendi haberleşme katmanınızı tasarlamış olursunuz.
Bu yapıya geliştiren ise paket içerisine "CheckSum, CRC" tarzı kontroller eklemektir.
Bunu kullanmazsanız ne olur ona bakalım.
ROBOT kelimesini göndereceksiniz.
Verici yolluyor.
Fakat alan taraf bir problemden dolayı ilk karakteri alamadı ve gecikti, ne olur ?
OBOT olarak okuduğunuz veriyi yanlış değerlendirirsiniz ve problem oluşur.
Bu yüzden önce sabit 2 tane karakter yollanır
[X][Y] olsun bunlar
Sonra verinin uzunluğu yollansın (Daha iyi oldu artık veri uzunluğu dinamik)
[L] diyelim bunada.
Sonra L uzunluğunda veri olsun
[ DATA(L) ]
Hadi birde CRC ekleyelim CRC16 olsun
[CRC16] (2 BYTE)
ve son olarak paket sonu karakteri.
[Z] olsun.
[X] [Y] [L BYTE DATA] [CRC16] [Z]
Alıcı taraf artık paketi alıp işler orasını sana bırakıyorum.
Bunu biraz daha geliştirip birde cevap paketi yapabilirsin.
Örneğin veriyi aldım veya alamadım bilgisi.
Hatta alamadıysa tekrar gönder gibi bir yapı daha hoş olur.
vs vs ...
Çok teşekkürler
Alıntı yapılan: baran123 - 28 Ağustos 2017, 09:18:59
Bu standart bir paketlemedir.
Haberleşme protokollerinin hepsinde veriler paketlenir.
Başın sabit bir karakter koyarsınız bu karakter gelince tamam benim verilerim geliyor diyebilirsiniz.
Verileri aldıktan sonra sonunda ise yine sabit bir karakterle verinin bittiğini anlarsınız.
Böylece hem verinin güvenliği bir puan artmış olur hemde kendi haberleşme katmanınızı tasarlamış olursunuz.
Bu yapıya geliştiren ise paket içerisine "CheckSum, CRC" tarzı kontroller eklemektir.
Bunu kullanmazsanız ne olur ona bakalım.
ROBOT kelimesini göndereceksiniz.
Verici yolluyor.
Fakat alan taraf bir problemden dolayı ilk karakteri alamadı ve gecikti, ne olur ?
OBOT olarak okuduğunuz veriyi yanlış değerlendirirsiniz ve problem oluşur.
Bu yüzden önce sabit 2 tane karakter yollanır
[X][Y] olsun bunlar
Sonra verinin uzunluğu yollansın (Daha iyi oldu artık veri uzunluğu dinamik)
[L] diyelim bunada.
Sonra L uzunluğunda veri olsun
[ DATA(L) ]
Hadi birde CRC ekleyelim CRC16 olsun
[CRC16] (2 BYTE)
ve son olarak paket sonu karakteri.
[Z] olsun.
[X] [Y] [L BYTE DATA] [CRC16] [Z]
Alıcı taraf artık paketi alıp işler orasını sana bırakıyorum.
Bunu biraz daha geliştirip birde cevap paketi yapabilirsin.
Örneğin veriyi aldım veya alamadım bilgisi.
Hatta alamadıysa tekrar gönder gibi bir yapı daha hoş olur.
vs vs ...
Ben yine bir şey soracağım kusura bakmayın.
Stm32 de nasıl bir kod yazmalıyım ki böyle bir data alayım. Örnek bir kod var mı acaba bu paket oluşturmayla ilgili internetten baktım ama bulamadım.
Gönderen kısmı şöyle yapabilirsin.
Ben masaüstünde yazdığım için böyle yaptım sen bunu uyarla STM ye.
Birde o veri gönderme fonksiyonunu daha güzel yapabilirsin böyle tek tek göndermek yerine __packed edip laps diye yollarsan daha kısa olur.
Bir örnek hazırladım fakat tamamlayamadım acele oldu kusura bakma alıcı kısmıda sen düzeltirsin.
Mantık bu şekilde olacak.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define CRC16_POLYNOMIAL (0xA001)
#define LEN_OF_DATA (8)
#define START_CHAR1 ('A') // 65
#define START_CHAR2 ('B') // 66
#define END_CHAR ('C') // 67
typedef struct {
uint8_t startChar1;
uint8_t startChar2;
uint8_t dataLen;
uint8_t data[LEN_OF_DATA];
union
{
struct {
uint8_t crcBytes[2];
};
struct {
uint16_t crc;
};
};
uint8_t endChar;
}DataPacket_TypeDef;
typedef enum {
PacketState_Wait = 0,
PacketState_Progress,
PacketState_Error,
PacketState_Completed
}PacketState_TypeDef;
DataPacket_TypeDef Tx_Packet;
DataPacket_TypeDef Rx_Packet;
static PacketState_TypeDef status = PacketState_Wait;
void USART_WriteData(uint8_t data);
uint8_t USART_ReadData(void);
void Packet_Init(DataPacket_TypeDef* DataPacket);
void Packet_Send(DataPacket_TypeDef* DataPacket);
void Packet_Show(DataPacket_TypeDef* DataPacket);
uint16_t CRC16_ArrayCalc(uint8_t buf[], uint8_t len);
PacketState_TypeDef Packet_Read(DataPacket_TypeDef* DataPacket, uint8_t rxData);
int main(int argc, char** argv)
{
uint8_t dataArray[8] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40};
uint8_t i;
for (i = 0; i < LEN_OF_DATA; i++)
Tx_Packet.data[i] = dataArray[i];
Packet_Init(&Tx_Packet);
Packet_Send(&Tx_Packet);
Packet_Show(&Tx_Packet);
uint8_t rxData;
for (;;)
{
rxData = USART_ReadData(); // elle karakter girilerek deneyebiliriz.
if (Packet_Read(&Rx_Packet, rxData) == PacketState_Completed)
{
Packet_Show(&Rx_Packet);
}
}
return (0);
}
void USART_WriteData(uint8_t data)
{
printf("%d\n\r", data);
}
uint8_t USART_ReadData(void)
{
uint8_t rxData;
scanf("%d", &rxData);
}
void Packet_Init(DataPacket_TypeDef* DataPacket)
{
DataPacket->startChar1 = START_CHAR1;
DataPacket->startChar2 = START_CHAR2;
DataPacket->endChar = END_CHAR;
DataPacket->dataLen = LEN_OF_DATA;
DataPacket->crc = CRC16_ArrayCalc(DataPacket->data, DataPacket->dataLen);
}
void Packet_Send(DataPacket_TypeDef* DataPacket)
{
USART_WriteData(DataPacket->startChar1);
USART_WriteData(DataPacket->startChar2);
USART_WriteData(DataPacket->dataLen);
int i;
for (i = 0; i < DataPacket->dataLen; i++)
USART_WriteData(DataPacket->data[i]);
USART_WriteData(DataPacket->crcBytes[1]);
USART_WriteData(DataPacket->crcBytes[0]);
USART_WriteData(DataPacket->endChar);
}
void Packet_Show(DataPacket_TypeDef* DataPacket)
{
printf("START CHAR 1 : %d\n\r", DataPacket->startChar1);
printf("START CHAR 2 : %d\n\r", DataPacket->startChar1);
printf("LEN OF DATA : %d\n\r", DataPacket->dataLen);
int i;
for (i = 0; i < DataPacket->dataLen; i++)
printf("BYTES[%d] = %d\n\r" ,i ,DataPacket->data[i]);
printf("CRC 16: %04X\n\r", DataPacket->crc);
printf("END CHAR : %d\n\r", DataPacket->endChar);
}
PacketState_TypeDef Packet_Read(DataPacket_TypeDef* DataPacket, uint8_t rxData)
{
static uint8_t state = 0;
static uint8_t index = 0;
switch (rxData)
{
case 0:
if (rxData == START_CHAR1);
{
status = PacketState_Progress;
DataPacket->startChar1 = START_CHAR1;
index = 0;
state = 1;
}
break;
case 1 :
if (rxData == START_CHAR2)
{
DataPacket->startChar2 = START_CHAR2;
state = 2;
}
break;
case 2:
DataPacket->dataLen = rxData;
state = 3;
break;
case 3:
if (index != DataPacket->dataLen)
{
DataPacket->data[index] = rxData;
index++;
}
else
state = 4;
break;
case 4:
DataPacket->crcBytes[1] = rxData;
state = 5;
break;
case 5:
DataPacket->crcBytes[0] = rxData;
state = 6;
break;
case 6:
if (rxData == END_CHAR)
{
DataPacket->endChar = END_CHAR;
status = PacketState_Completed;
state = 0;
}
else
status = PacketState_Error;
break;
}
}
uint16_t CRC16_ArrayCalc(uint8_t buf[], uint8_t len)
{
uint16_t crc = 0xFFFF;
for (uint8_t pos = 0; pos < len; pos++)
{
crc ^= (uint16_t)buf[pos];
for (uint8_t i = 8; i != 0; i--)
{
if ((crc & 0x0001) != 0)
{
crc >>= 1;
crc ^= CRC16_POLYNOMIAL;
}
else
crc >>= 1;
}
}
return crc;
}
Alıntı yapılan: baran123 - 28 Ağustos 2017, 19:03:34
Gönderen kısmı şöyle yapabilirsin.
Ben masaüstünde yazdığım için böyle yaptım sen bunu uyarla STM ye.
Birde o veri gönderme fonksiyonunu daha güzel yapabilirsin böyle tek tek göndermek yerine __packed edip laps diye yollarsan daha kısa olur.
Bir örnek hazırladım fakat tamamlayamadım acele oldu kusura bakma alıcı kısmıda sen düzeltirsin.
Mantık bu şekilde olacak.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define CRC16_POLYNOMIAL (0xA001)
#define LEN_OF_DATA (8)
#define START_CHAR1 ('A') // 65
#define START_CHAR2 ('B') // 66
#define END_CHAR ('C') // 67
typedef struct {
uint8_t startChar1;
uint8_t startChar2;
uint8_t dataLen;
uint8_t data[LEN_OF_DATA];
union
{
struct {
uint8_t crcBytes[2];
};
struct {
uint16_t crc;
};
};
uint8_t endChar;
}DataPacket_TypeDef;
typedef enum {
PacketState_Wait = 0,
PacketState_Progress,
PacketState_Error,
PacketState_Completed
}PacketState_TypeDef;
DataPacket_TypeDef Tx_Packet;
DataPacket_TypeDef Rx_Packet;
static PacketState_TypeDef status = PacketState_Wait;
void USART_WriteData(uint8_t data);
uint8_t USART_ReadData(void);
void Packet_Init(DataPacket_TypeDef* DataPacket);
void Packet_Send(DataPacket_TypeDef* DataPacket);
void Packet_Show(DataPacket_TypeDef* DataPacket);
uint16_t CRC16_ArrayCalc(uint8_t buf[], uint8_t len);
PacketState_TypeDef Packet_Read(DataPacket_TypeDef* DataPacket, uint8_t rxData);
int main(int argc, char** argv)
{
uint8_t dataArray[8] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40};
uint8_t i;
for (i = 0; i < LEN_OF_DATA; i++)
Tx_Packet.data[i] = dataArray[i];
Packet_Init(&Tx_Packet);
Packet_Send(&Tx_Packet);
Packet_Show(&Tx_Packet);
uint8_t rxData;
for (;;)
{
rxData = USART_ReadData(); // elle karakter girilerek deneyebiliriz.
if (Packet_Read(&Rx_Packet, rxData) == PacketState_Completed)
{
Packet_Show(&Rx_Packet);
}
}
return (0);
}
void USART_WriteData(uint8_t data)
{
printf("%d\n\r", data);
}
uint8_t USART_ReadData(void)
{
uint8_t rxData;
scanf("%d", &rxData);
}
void Packet_Init(DataPacket_TypeDef* DataPacket)
{
DataPacket->startChar1 = START_CHAR1;
DataPacket->startChar2 = START_CHAR2;
DataPacket->endChar = END_CHAR;
DataPacket->dataLen = LEN_OF_DATA;
DataPacket->crc = CRC16_ArrayCalc(DataPacket->data, DataPacket->dataLen);
}
void Packet_Send(DataPacket_TypeDef* DataPacket)
{
USART_WriteData(DataPacket->startChar1);
USART_WriteData(DataPacket->startChar2);
USART_WriteData(DataPacket->dataLen);
int i;
for (i = 0; i < DataPacket->dataLen; i++)
USART_WriteData(DataPacket->data[i]);
USART_WriteData(DataPacket->crcBytes[1]);
USART_WriteData(DataPacket->crcBytes[0]);
USART_WriteData(DataPacket->endChar);
}
void Packet_Show(DataPacket_TypeDef* DataPacket)
{
printf("START CHAR 1 : %d\n\r", DataPacket->startChar1);
printf("START CHAR 2 : %d\n\r", DataPacket->startChar1);
printf("LEN OF DATA : %d\n\r", DataPacket->dataLen);
int i;
for (i = 0; i < DataPacket->dataLen; i++)
printf("BYTES[%d] = %d\n\r" ,i ,DataPacket->data[i]);
printf("CRC 16: %04X\n\r", DataPacket->crc);
printf("END CHAR : %d\n\r", DataPacket->endChar);
}
PacketState_TypeDef Packet_Read(DataPacket_TypeDef* DataPacket, uint8_t rxData)
{
static uint8_t state = 0;
static uint8_t index = 0;
switch (rxData)
{
case 0:
if (rxData == START_CHAR1);
{
status = PacketState_Progress;
DataPacket->startChar1 = START_CHAR1;
index = 0;
state = 1;
}
break;
case 1 :
if (rxData == START_CHAR2)
{
DataPacket->startChar2 = START_CHAR2;
state = 2;
}
break;
case 2:
DataPacket->dataLen = rxData;
state = 3;
break;
case 3:
if (index != DataPacket->dataLen)
{
DataPacket->data[index] = rxData;
index++;
}
else
state = 4;
break;
case 4:
DataPacket->crcBytes[1] = rxData;
state = 5;
break;
case 5:
DataPacket->crcBytes[0] = rxData;
state = 6;
break;
case 6:
if (rxData == END_CHAR)
{
DataPacket->endChar = END_CHAR;
status = PacketState_Completed;
state = 0;
}
else
status = PacketState_Error;
break;
}
}
uint16_t CRC16_ArrayCalc(uint8_t buf[], uint8_t len)
{
uint16_t crc = 0xFFFF;
for (uint8_t pos = 0; pos < len; pos++)
{
crc ^= (uint16_t)buf[pos];
for (uint8_t i = 8; i != 0; i--)
{
if ((crc & 0x0001) != 0)
{
crc >>= 1;
crc ^= CRC16_POLYNOMIAL;
}
else
crc >>= 1;
}
}
return crc;
}
Çok teşekkür ederim. Gerçekten baya emek vermişsiniz.
Python kısmında gönderdiğim bir dizi var bu 4 açı değerini pyhton'dan alıyorum. Açı değerini pyhton tarafında hex'e çeviriyorum, Stm'e dizi olarak gönderiyorum. Bu değeri duty cycle'a stm tarafında çevirip motorlara gönderiyorum. Stm32 alıcı taraf olduğundan, rx kullanmam yeterli midir ?