текучка

This commit is contained in:
klassents committed 2024-10-09 11:27:37 +07:00
1 parent b920713163
commit 47ff1ce4eb
7 files changed
+141 -86

No files matched your search

@@ -0,0 +1,84 @@
/*
Software serial multiple serial test
Receives from the two software serial ports,
sends to the hardware serial port.
In order to listen on a software port, you call port.listen().
When using two software serial ports, you have to switch ports
by listen()ing on each one in turn. Pick a logical time to switch
ports, like the end of an expected transmission, or when the
buffer is empty. This example switches ports when there is nothing
more to read from a port
The circuit:
Two devices which communicate serially are needed.
* First serial device's TX attached to digital pin 2(RX), RX to pin 6(TX)
* Second serial device's TX attached to digital pin 8(RX), RX to pin 10(TX)
Note:
Not all pins on the Elbear Ace-Uno support interrupts,
so only the following can be used for RX:
2, 3, 4, 5, 8, 9
created 18 Apr. 2011
modified 19 March 2016
by Tom Igoe
based on Mikal Hart's twoPortRXExample
This example code is in the public domain.
*/
#include <SoftwareSerial.h>
// software serial #1: RX = digital pin 2, TX = digital pin 6
SoftwareSerial portOne(2, 6);
// software serial #2: RX = digital pin 8, TX = digital pin 10
SoftwareSerial portTwo(8, 10);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// Start each software serial port
portOne.begin(57600);
portTwo.begin(57600);
portTwo.listen();
delay(2000);
}
void loop() {
// By default, the last initialized port is listening.
// when you want to listen on a port, explicitly select it:
portOne.listen();
Serial.println("Data from port one:");
// while there is data coming in, read it
// and send to the hardware serial port:
while (portOne.available() > 0) {
char inByte = portOne.read();
Serial.write(inByte);
}
// blank line to separate data from the two ports:
Serial.println();
delay(2000);
// // Now listen on the second port
// portTwo.listen();
// // while there is data coming in, read it
// // and send to the hardware serial port:
// Serial.println("Data from port two:");
// while (portTwo.available() > 0) {
// char inByte = portTwo.read();
// Serial.write(inByte);
// }
// // blank line to separate data from the two ports:
// Serial.println();
// delay(2000);
}
+27 -36
View File
@@ -89,15 +89,13 @@ void SoftwareSerial::recv() // .ram_text
bool rxState = (bool)GPIO_READ_PIN((GPIO_TypeDef *)_receivePortRegister, (HAL_PinsTypeDef)_receiveBitMask);
if (_inverse_logic ? rxState : !rxState)
{
// Disable further interrupts during reception, this prevents
// triggering another interrupt directly after we return, which can
// cause problems at higher baudrates.
// Disable further interrupts during reception, this prevents triggering another interrupt
// directly after we return, which can cause problems at higher baudrates.
setRxIntMsk(false); // __always_inline__
// Wait approximately 1/2 of a bit width to "center" the sample
if (_rx_delay_centering > 0)
tunedDelay(_rx_delay_centering); // .ram_text
GPIO_0->OUTPUT_ ^= GPIO_PIN_1;
// Read each of the 8 bits
uint8_t data = 0;
@@ -105,13 +103,9 @@ void SoftwareSerial::recv() // .ram_text
{
tunedDelay(_rx_delay_intrabit);
data >>= 1;
GPIO_0->OUTPUT_ ^= GPIO_PIN_1;
if (GPIO_READ_PIN((GPIO_TypeDef *)_receivePortRegister, (HAL_PinsTypeDef)_receiveBitMask))
data |= 0x80;
}
if (_inverse_logic)
data = ~data;
@@ -124,17 +118,13 @@ void SoftwareSerial::recv() // .ram_text
_receive_buffer_tail = next;
}
else
{
_buffer_overflow = true;
}
// skip the stop bit
tunedDelay(_rx_delay_stopbit);
GPIO_0->OUTPUT_ ^= GPIO_PIN_1;
// Re-enable interrupts when we're sure to be inside the stop bit
setRxIntMsk(true);
}
GPIO_IRQ_CLEAR_ALL();
}
@@ -151,7 +141,7 @@ void SoftwareSerial::handle_interrupt() // .ram_text
{
if (active_object)
{
active_object->recv();
active_object->recv(); // .ram_text
}
}
@@ -187,29 +177,33 @@ SoftwareSerial::~SoftwareSerial()
void SoftwareSerial::setTX(uint8_t tx)
{
// First configure then write because writing pin didn't work until config is applied
// save pin and port info
_transmitBitMask = (uint16_t)digitalPinToBitMask(tx);
_transmitPortRegister = (uint32_t)digitalPinToPort(tx);
// set state before tx pin initialization to prevent false start bit
if (_inverse_logic)
GPIO_CLEAR_PIN((GPIO_TypeDef *)_transmitPortRegister, (HAL_PinsTypeDef)_transmitBitMask);
else
GPIO_SET_PIN((GPIO_TypeDef *)_transmitPortRegister, (HAL_PinsTypeDef)_transmitBitMask);
// init pin as output
pinMode(tx, OUTPUT);
digitalWrite(tx, _inverse_logic ? LOW : HIGH);
_transmitBitMask = (uint16_t)digitalPinToBitMask(tx); // save tx bit mask
_transmitPortRegister = (uint32_t)digitalPinToPort(tx); // save tx port adress
}
void SoftwareSerial::setRX(uint8_t rx)
{
_receiveBitMask = (uint16_t)digitalPinToBitMask(rx); // save rx bit mask
_receivePortRegister = (uint32_t)digitalPinToPort(rx); // save rx port adress
if (!_inverse_logic)
pinMode(rx, INPUT_PULLUP); // pullup for normal logic
else
pinMode(rx, INPUT);
// Save gpio_line for turning on/off interrupts
// save pin, port and gpio_line info
_receiveBitMask = (uint16_t)digitalPinToBitMask(rx);
_receivePortRegister = (uint32_t)digitalPinToPort(rx);
_int_maskLine = digitalPinToGpioIntLine(_receivePin);
// Init interrupt line
HAL_GPIO_InitInterruptLine((HAL_GPIO_Line_Config)digitalPinToGpioIntMux(_receivePin),
_inverse_logic ? GPIO_INT_MODE_RISING : GPIO_INT_MODE_FALLING);
GPIO_IRQ_LINE_DISABLE(_int_maskLine); // turn off int line (it turning on while line init)
HAL_EPIC_MaskEdgeSet(HAL_EPIC_GPIO_IRQ_MASK); // turn on the mask in EPIC
// attach interrupt to rx pin if available
attachInterrupt(digitalPinToInterrupt(_receivePin), softSerial_handler_wrapper, _inverse_logic ? RISING : FALLING);
if (!_inverse_logic)
// turn on pull up for rx if logic is not inverse
HAL_GPIO_PinConfig((GPIO_TypeDef *)_receivePortRegister, (HAL_PinsTypeDef)_receiveBitMask,
HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_UP, HAL_GPIO_DS_2MA);
// turn off int line for while (it turning on in attachInterrupt())
GPIO_IRQ_LINE_DISABLE(_int_maskLine);
}
uint32_t SoftwareSerial::subtract_cap(uint32_t num, uint16_t sub)
@@ -235,10 +229,11 @@ void SoftwareSerial::begin(long speed)
// Precalculate the various delays in number of ticks
uint32_t bit_delay = F_CPU / speed;
// init tx
setTX(_transmitPin);
_tx_delay = subtract_cap(bit_delay, 35); // 1 bit delay while transmitting data
// Only setup rx when we have a valid INT for this pin
// init rx only when we have a valid INT for this pin
if (digitalPinToInterrupt(_receivePin) != NOT_AN_INTERRUPT)
{
// set pin config
@@ -260,10 +255,6 @@ void SoftwareSerial::begin(long speed)
tunedDelay(_tx_delay); // if we were low this establishes the end
// todo убрать
HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_0, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_1, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
listen();
}
@@ -363,4 +354,4 @@ int SoftwareSerial::peek()
// Read from "head"
return _receive_buffer[_receive_buffer_head];
}
}